MSDN Magazine - October 2007 - (Page 57) For this reason, if a callback function might block while executing, the maximum size of the thread pool must be larger than the number of available processors in the system in order to realize the maximum concurrency that the hardware supports. Ideally, a callback function should never block. A callback function that blocks not only decreases concurrency but also decreases the level of worker thread reuse. Because of this, it’s definitely worth making the effort to eliminate or minimize the length of time a callback function blocks. You can reduce that time if you understand what the callback is blocking on. For example, if the callback is performing synchronous I/O, consider changing it to asynchronous I/O that completes on the thread pool instead. And look to minimize any synchronization that must occur between callback functions because lock contention can cause blocking. If most of the callback functions don’t block, the thread pool can be sized to contain fewer threads in excess of the number of available processors. If most of the callback functions are going to end up blocking, the thread pool should be sized to contain many more worker threads than the number of available processors. In this case, most threads will end up in a wait state. As callback functions complete, in order to maximize overall throughput the thread pool will hold back worker threads, reducing the number of runnable threads to a number that’s optimal for the processor configuration. The point is that you want to size the thread pool so that when there are tasks to run and sufficient processor bandwidth available, the pool can create more threads to do work. However, if you find that your application actually uses an inordinately large number of threads, like the 500 in the default setting, or if there is excessive context switching cost, the application is not designed properly and you need to examine your code using the performance monitor and a code profiler to determine where improvements can be made. Once you’re finished with the thread pool, it should be closed using the CloseThreadpool function. The thread pool is closed immediately if there are no outstanding callback objects that are bound to the thread pool. If there are, then the thread pool is released asynchronously when those outstanding objects are freed. Figure 3 Callback Environment APIs VOID InitializeThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe); VOID DestroyThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe); VOID SetThreadpoolCallbackPool(PTP_CALLBACK_ENVIRON pcbe, PTP_POOL ptpp); VOID SetThreadpoolCallbackLibrary(PTP_CALLBACK_ENVIRON pcbe, PVOID mod); VOID SetThreadpoolCallbackRunsLong(PTP_CALLBACK_ENVIRON pcbe); VOID SetThreadpoolCallbackCleanupGroup(PTP_CALLBACK_ENVIRON pcbe, PTP_CLEANUP_GROUP ptpcg, PTP_CLEANUP_GROUP_CANCEL_CALLBACK pfng); Callback Environment Objects Now that you understand how to create a thread pool, the next step is to look at what a callback environment object is and how it should be used. A callback environment object is used to bind a thread pool instance to the instances of thread pool callback objects your application creates to actually do work on the thread pool. A callback environment object also allows you to attach a cleanup group object, which makes the cleanup of the thread pool callback objects simpler. Cleanup groups will be fully discussed later on in the article. The callback environment APIs are shown in Figure 3. The first step in creating a callback environment is to either declare a TP_CALL_BACK_ENVIRON structure in static storage, on the stack, or allocate one from the heap. The next step is to initialize it using the InitializeThreadpoolEnvironment function, which takes a pointer to TP_CALLBACK_ENVIRON. Fi- nally, to associate a thread pool with the callback environment, use SetThreadpoolCallbackPool. If you don’t associate a thread pool with the callback environment or if NULL is specified in the call to SetThreadpoolCallbackPool, the process’s default thread pool will be used. As you’ll see, the callback environment is eventually used to create the various thread pool callback object instances. Once your application has finished modifying the properties of the callback environment and creating all the instances of the callback objects it needs, the callback environment should be destroyed using the DestroyThreadpoolEnvironment function. The SetThreadpoolCallbackRunsLong API is used to give a hint to the thread pool that the callback functions associated with this environment may not return quickly. You’ll see later how this affects the result returned from calling the API function CallbackMayRunLong. I mentioned earlier that the legacy thread pool lacked support for an application that needed to determine when it was safe to unload a DLL containing a callback function that was to be executed on the thread pool. The new thread pool API provides the SetThreadpoolCallbackLibrary function to guarantee that a library remains loaded as long as a callback function inside a DLL is still executing. Essentially, what happens is that before the callback function is invoked, the operating system’s loader lock (which is always held when a DLL is in the process of being loaded or unloaded) is acquired and the DLL’s reference count is incremented; the loader Size the thread pool so that lock is then released. Afwhen there are tasks to run ter the callback completes and sufficient processor execution, the loader lock is acquired again to decrebandwidth available, the ment the reference count. pool can create more This makes it impossible threads to do work. for the DLL to be unloaded while a callback function is executing. Note that while callbacks are pending on the thread pool’s queue, the reference count on the DLL remains unchanged. This means that a DLL can be unloaded with callbacks pending. However, it is the job of the DllMain function that you write to make sure that you handle the DLL_PROCESS_DETACH event and cancel all pending callbacks. I’ll get to this in a bit. Work Objects A work object is used to cause the thread pool to invoke a callback function asynchronously on a worker thread. The CreateThreadThread Pools october2007 57
Table of Contents Feed for the Digital Edition of MSDN Magazine - October 2007 Cover Contents Toolbox CLR Inside Out Basic Instincts Data Points Cutting Edge Pooled Threads WPF Threads Parallel Linq Parallel Performance Mobile Apps Test Run Foundations Windows with C++ Netting C++ .NET Matters { End Bracket } Net Nuptials MSDN Magazine - October 2007 MSDN Magazine - October 2007 - Contents (Page Cover1) MSDN Magazine - October 2007 - Contents (Page Cover2) MSDN Magazine - October 2007 - Contents (Page 1) MSDN Magazine - October 2007 - Contents (Page 2) MSDN Magazine - October 2007 - Contents (Page 3) MSDN Magazine - October 2007 - Contents (Page 4) MSDN Magazine - October 2007 - Contents (Page 5) MSDN Magazine - October 2007 - Contents (Page 6) MSDN Magazine - October 2007 - Contents (Page 7) MSDN Magazine - October 2007 - Contents (Page 8) MSDN Magazine - October 2007 - Contents (Page 9) MSDN Magazine - October 2007 - Contents (Page 10) MSDN Magazine - October 2007 - Toolbox (Page 11) MSDN Magazine - October 2007 - Toolbox (Page 12) MSDN Magazine - October 2007 - Toolbox (Page 13) MSDN Magazine - October 2007 - Toolbox (Page 14) MSDN Magazine - October 2007 - Toolbox (Page 15) MSDN Magazine - October 2007 - Toolbox (Page 16) MSDN Magazine - October 2007 - CLR Inside Out (Page 17) MSDN Magazine - October 2007 - CLR Inside Out (Page 18) MSDN Magazine - October 2007 - CLR Inside Out (Page 19) MSDN Magazine - October 2007 - CLR Inside Out (Page 20) MSDN Magazine - October 2007 - CLR Inside Out (Page 21) MSDN Magazine - October 2007 - CLR Inside Out (Page 22) MSDN Magazine - October 2007 - CLR Inside Out (Page 23) MSDN Magazine - October 2007 - CLR Inside Out (Page 24) MSDN Magazine - October 2007 - CLR Inside Out (Page 25) MSDN Magazine - October 2007 - CLR Inside Out (Page 26) MSDN Magazine - October 2007 - CLR Inside Out (Page 27) MSDN Magazine - October 2007 - CLR Inside Out (Page 28) MSDN Magazine - October 2007 - CLR Inside Out (Page 29) MSDN Magazine - October 2007 - CLR Inside Out (Page 30) MSDN Magazine - October 2007 - Basic Instincts (Page 31) MSDN Magazine - October 2007 - Basic Instincts (Page 32) MSDN Magazine - October 2007 - Basic Instincts (Page 33) MSDN Magazine - October 2007 - Basic Instincts (Page 34) MSDN Magazine - October 2007 - Basic Instincts (Page 35) MSDN Magazine - October 2007 - Basic Instincts (Page 36) MSDN Magazine - October 2007 - Data Points (Page 37) MSDN Magazine - October 2007 - Data Points (Page 38) MSDN Magazine - October 2007 - Data Points (Page 39) MSDN Magazine - October 2007 - Data Points (Page 40) MSDN Magazine - October 2007 - Data Points (Page 41) MSDN Magazine - October 2007 - Data Points (Page 42) MSDN Magazine - October 2007 - Cutting Edge (Page 43) MSDN Magazine - October 2007 - Cutting Edge (Page 44) MSDN Magazine - October 2007 - Cutting Edge (Page 45) MSDN Magazine - October 2007 - Cutting Edge (Page 46) MSDN Magazine - October 2007 - Cutting Edge (Page 47) MSDN Magazine - October 2007 - Cutting Edge (Page 48) MSDN Magazine - October 2007 - Cutting Edge (Page 49) MSDN Magazine - October 2007 - Cutting Edge (Page 50) MSDN Magazine - October 2007 - Cutting Edge (Page 51) MSDN Magazine - October 2007 - Cutting Edge (Page 52) MSDN Magazine - October 2007 - Cutting Edge (Page 53) MSDN Magazine - October 2007 - Pooled Threads (Page 54) MSDN Magazine - October 2007 - Pooled Threads (Page 55) MSDN Magazine - October 2007 - Pooled Threads (Page 56) MSDN Magazine - October 2007 - Pooled Threads (Page 57) MSDN Magazine - October 2007 - Pooled Threads (Page 58) MSDN Magazine - October 2007 - Pooled Threads (Page 59) MSDN Magazine - October 2007 - Pooled Threads (Page 60) MSDN Magazine - October 2007 - Pooled Threads (Page 61) MSDN Magazine - October 2007 - Pooled Threads (Page 62) MSDN Magazine - October 2007 - Pooled Threads (Page 63) MSDN Magazine - October 2007 - Pooled Threads (Page 64) MSDN Magazine - October 2007 - Pooled Threads (Page 65) MSDN Magazine - October 2007 - WPF Threads (Page 66) MSDN Magazine - October 2007 - WPF Threads (Page 67) MSDN Magazine - October 2007 - WPF Threads (Page 68) MSDN Magazine - October 2007 - WPF Threads (Page 69) MSDN Magazine - October 2007 - Parallel Linq (Page 70) MSDN Magazine - October 2007 - Parallel Linq (Page 71) MSDN Magazine - October 2007 - Parallel Linq (Page 72) MSDN Magazine - October 2007 - Parallel Linq (Page 73) MSDN Magazine - October 2007 - Parallel Linq (Page 74) MSDN Magazine - October 2007 - Parallel Linq (Page 75) MSDN Magazine - October 2007 - Parallel Linq (Page 76) MSDN Magazine - October 2007 - Parallel Linq (Page 77) MSDN Magazine - October 2007 - Parallel Linq (Page 78) MSDN Magazine - October 2007 - Parallel Performance (Page 79) MSDN Magazine - October 2007 - Parallel Performance (Page 80) MSDN Magazine - October 2007 - Parallel Performance (Page 81) MSDN Magazine - October 2007 - Parallel Performance (Page 82) MSDN Magazine - October 2007 - Parallel Performance (Page 83) MSDN Magazine - October 2007 - Parallel Performance (Page 84) MSDN Magazine - October 2007 - Parallel Performance (Page 85) MSDN Magazine - October 2007 - Parallel Performance (Page 86) MSDN Magazine - October 2007 - Parallel Performance (Page 87) MSDN Magazine - October 2007 - Parallel Performance (Page 88) MSDN Magazine - October 2007 - Parallel Performance (Page 89) MSDN Magazine - October 2007 - Parallel Performance (Page 90) MSDN Magazine - October 2007 - Mobile Apps (Page 91) MSDN Magazine - October 2007 - Mobile Apps (Page 92) MSDN Magazine - October 2007 - Mobile Apps (Page 93) MSDN Magazine - October 2007 - Mobile Apps (Page 94) MSDN Magazine - October 2007 - Mobile Apps (Page 95) MSDN Magazine - October 2007 - Mobile Apps (Page 96) MSDN Magazine - October 2007 - Mobile Apps (Page 97) MSDN Magazine - October 2007 - Mobile Apps (Page 98) MSDN Magazine - October 2007 - Mobile Apps (Page 99) MSDN Magazine - October 2007 - Mobile Apps (Page 100) MSDN Magazine - October 2007 - Test Run (Page 101) MSDN Magazine - October 2007 - Test Run (Page 102) MSDN Magazine - October 2007 - Test Run (Page 103) MSDN Magazine - October 2007 - Test Run (Page 104) MSDN Magazine - October 2007 - Test Run (Page 105) MSDN Magazine - October 2007 - Test Run (Page 106) MSDN Magazine - October 2007 - Test Run (Page 107) MSDN Magazine - October 2007 - Test Run (Page 108) MSDN Magazine - October 2007 - Test Run (Page 109) MSDN Magazine - October 2007 - Test Run (Page 110) MSDN Magazine - October 2007 - Test Run (Page 111) MSDN Magazine - October 2007 - Test Run (Page 112) MSDN Magazine - October 2007 - Test Run (Page 113) MSDN Magazine - October 2007 - Test Run (Page 114) MSDN Magazine - October 2007 - Foundations (Page 115) MSDN Magazine - October 2007 - Foundations (Page 116) MSDN Magazine - October 2007 - Foundations (Page 117) MSDN Magazine - October 2007 - Foundations (Page 118) MSDN Magazine - October 2007 - Foundations (Page 119) MSDN Magazine - October 2007 - Foundations (Page 120) MSDN Magazine - October 2007 - Foundations (Page 121) MSDN Magazine - October 2007 - Foundations (Page 122) MSDN Magazine - October 2007 - Foundations (Page 123) MSDN Magazine - October 2007 - Foundations (Page 124) MSDN Magazine - October 2007 - Windows with C++ (Page 125) MSDN Magazine - October 2007 - Windows with C++ (Page 126) MSDN Magazine - October 2007 - Windows with C++ (Page 127) MSDN Magazine - October 2007 - Windows with C++ (Page 128) MSDN Magazine - October 2007 - Windows with C++ (Page 129) MSDN Magazine - October 2007 - Windows with C++ (Page 130) MSDN Magazine - October 2007 - Windows with C++ (Page 131) MSDN Magazine - October 2007 - Windows with C++ (Page 132) MSDN Magazine - October 2007 - Netting C++ (Page 133) MSDN Magazine - October 2007 - Netting C++ (Page 134) MSDN Magazine - October 2007 - Netting C++ (Page 135) MSDN Magazine - October 2007 - Netting C++ (Page 136) MSDN Magazine - October 2007 - .NET Matters (Page 137) MSDN Magazine - October 2007 - .NET Matters (Page 138) MSDN Magazine - October 2007 - .NET Matters (Page 139) MSDN Magazine - October 2007 - .NET Matters (Page 140) MSDN Magazine - October 2007 - .NET Matters (Page 141) MSDN Magazine - October 2007 - .NET Matters (Page 142) MSDN Magazine - October 2007 - .NET Matters (Page 143) MSDN Magazine - October 2007 - Net Nuptials (Page 144) MSDN Magazine - October 2007 - Net Nuptials (Page Cover3) MSDN Magazine - October 2007 - Net Nuptials (Page Cover4)
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.