Windows系統線程池+利用windows內建的線程池

來源:互聯網
上載者:User

come from:http://www.fuzhijie.me/?p=65
一直想弄明白Windows的IO完成連接埠是什麼,這個詞語每每出現在我眼前時總是伴隨著鮮花和讚美,因此我便將其同許多我從來沒搞懂過的東西一起歸為神秘一類。這兩天一直在看《Windows核心編程》,學到了不少東西,但是同別的英文經典一樣,中文版經常讓我感覺不知所云,我很不喜歡書中的例子都是用C++來寫,並且都有圖形介面,這阻礙了初學者理解問題的本質,並不是每個人都熟悉Windows的圖形介面編程,Windows的API不僅個數多,許多API參數也非常多,如果僅僅是簡單類型也就罷了,許多參數又會是複雜的結構體,相比之下,Unix的系統調用就簡潔多了。我打算循序漸進,先學習了下Windows內建的線程池的使用,這個東西實現得挺好的,Linux沒有提供等同物。

MSDN中對線程池的使用只給出了一個執行個體,相關的代碼網上少得可憐,我只能對這例子視若珍寶,好好研究了一番,去掉一些旁枝末節,添加點注釋吧,就當作是讀書劄記吧。

《Windows核心編程》中將線程池允許我們做的事情歸為四類,分別如下:
情景1:以非同步方式調用函數
情景2:每隔一段時間調用一個函數
情景3:在核心對象觸發時調用一個函數
情景4:在非同步I/O請求完成時調用一個函數

MSDN中的這個例子示範了前三種情景,這三種情景下的回呼函數的簽名各不一樣。原程式中沒有給清理組設定回呼函數,我寫了一個清理回呼函數,也只是簡單地列印出運行代碼的線程號等資訊而已。

//// Thread pool wait callback function template//////注意這三種回呼函數的簽名,它們都沒有傳回值VOIDCALLBACKMyWaitCallback(      PTP_CALLBACK_INSTANCE Instance,      PVOID                 Parameter,      PTP_WAIT              Wait,      TP_WAIT_RESULT        WaitResult      ){printf("%u in MyWaitCallback\n", GetCurrentThreadId());} //// Thread pool timer callback function template//VOIDCALLBACKMyTimerCallback(    PTP_CALLBACK_INSTANCE Instance,    PVOID                 Parameter,    PTP_TIMER             Timer    ){printf("(%u) in MyTimerCallback\n", GetCurrentThreadId());} //// This is the thread pool work callback function.// The callback demonstrates correct behavior when changing the// state of the thread inside the callback function.//// Any changes to the thread state must be restored to original// before exiting the callback routine.//VOIDCALLBACKMyWorkCallback(      PTP_CALLBACK_INSTANCE Instance,      PVOID                 Parameter,      PTP_WORK              Work      ){printf("(%u) in MyWorkCallback\n", GetCurrentThreadId());} VOIDCALLBACKMyCleanupCallback(      PVOID pvObjectContext,      PVOID pvCleanupContext      ){printf("(%u) in MyCleanupCallback\n", GetCurrentThreadId());} VOIDDemoCleanupPersistentWorkTimer(){BOOL bRet = FALSE;PTP_WORK work = NULL;PTP_TIMER timer = NULL;PTP_POOL pool = NULL;TP_CALLBACK_ENVIRON CallBackEnviron;PTP_CLEANUP_GROUP cleanupgroup = NULL;FILETIME FileDueTime;ULARGE_INTEGER ulDueTime;UINT rollback = 0; printf("(%u)in DemoCleanupPersistentWorkTimer\n", GetCurrentThreadId()); //初始化很重要,否則運行到CreateThreadpoolWork將會出錯//可以在偵錯模式下看看TP_CALLBACK_ENVIRON結構體的內容InitializeThreadpoolEnvironment(&CallBackEnviron); //// Create a custom, dedicated thread pool//pool = CreateThreadpool(NULL); if (NULL == pool) {_tprintf(_T("CreateThreadpool failed. LastError: %u\n"),GetLastError());goto main_cleanup;} rollback = 1; // pool creation succeeded //// The thread pool is made persistent simply by setting// both the minimum and maximum threads to 1.////將最大值和最小值都設定為1,若提交幾個工作項目時,所有的工作項目都由這一個線程完成//如果可以開啟多個線程,可以看到會有好幾個線程一起來完成這些工作項目SetThreadpoolThreadMaximum(pool, 1); bRet = SetThreadpoolThreadMinimum(pool, 4); if (FALSE == bRet) {_tprintf(_T("SetThreadpoolThreadMinimum failed. LastError: %u\n"), GetLastError());goto main_cleanup;} //// Create a cleanup group for this thread pool//cleanupgroup = CreateThreadpoolCleanupGroup(); if (NULL == cleanupgroup) {_tprintf(_T("CreateThreadpoolCleanupGroup failed. LastError: %u\n"), GetLastError());goto main_cleanup;} rollback = 2;  // Cleanup group creation succeeded //// Associate the callback environment with our thread pool//SetThreadpoolCallbackPool(&CallBackEnviron, pool); //// Associate the cleanup group with our thread pool//SetThreadpoolCallbackCleanupGroup(&CallBackEnviron,cleanupgroup,&MyCleanupCallback); //// Create work with the callback environment////使用的線程池被包含在CallBackEnviron參數中//如果此處傳遞NULL進去,將使用一個預設的線程池work = CreateThreadpoolWork((PTP_WORK_CALLBACK) MyWorkCallback,NULL,&CallBackEnviron); if (NULL == work) {_tprintf(_T("CreateThreadpoolWork failed. LastError: %u\n"),GetLastError());goto main_cleanup;} rollback = 3;  // Creation of work succeeded //// Submit the work to the pool. Because this was a pre-allocated// work item (using CreateThreadpoolWork), it is guaranteed// to execute////可以多提交幾個工作項目試試看,SubmitThreadpoolWork(work);SubmitThreadpoolWork(work);SubmitThreadpoolWork(work);SubmitThreadpoolWork(work); //// Create a timer with the same callback environment//timer = CreateThreadpoolTimer((PTP_TIMER_CALLBACK) MyTimerCallback,NULL, &CallBackEnviron); if (NULL == timer) {_tprintf(_T("CreateThreadpoolTimer failed. LastError: %u\n"),GetLastError());goto main_cleanup;} rollback = 4;  // Timer creation succeeded //// Set the timer to fire in one second////如果為正值,則表示絕對時間,從1600年1月1日開始計算,單位為納秒//如果為負值,則表示相對時間,單位為微秒//兩種情況下單位不一樣哦。ulDueTime.QuadPart = (LONGLONG) -(100000000);FileDueTime.dwHighDateTime = ulDueTime.HighPart;FileDueTime.dwLowDateTime  = ulDueTime.LowPart; //定時器只觸發一次SetThreadpoolTimer(timer,&FileDueTime,0,0); //// Delay for the timer to be fired////等待線程池中的線程完成定時器中的工作,注意這兒睡眠的值//要大於上面定時器觸發的值,否則就看不到結果了。Sleep(15000); //// Wait for all callbacks to finish.// CloseThreadpoolCleanupGroupMembers also calls the cleanup// functions for all the individual objects in the specified// cleanup group.////此時主線程會調用MyCleanupCallback兩次,我還沒怎麼明白清理組的使用方法CloseThreadpoolCleanupGroupMembers(cleanupgroup,FALSE,NULL); //// Already cleaned up the work item with the// CloseThreadpoolCleanupGroupMembers, so set rollback to 2.//rollback = 2;goto main_cleanup; main_cleanup://// Clean up any individual pieces manually// Notice the fall through structure of the switch.// Clean up in reverse order.// switch (rollback) {case 4:case 3:// Clean up the cleanup group membersCloseThreadpoolCleanupGroupMembers(cleanupgroup,FALSE, NULL);case 2:// Clean up the cleanup groupCloseThreadpoolCleanupGroup(cleanupgroup); case 1:// Clean up the poolCloseThreadpool(pool); default:break;} return;} VOIDDemoNewRegisterWait(){PTP_WAIT Wait = NULL;HANDLE hEvent = NULL;UINT i = 0;UINT rollback = 0; printf("(%u)in DemoNewRegisterWait\n", GetCurrentThreadId()); //// Create an auto-reset event//hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (NULL == hEvent) {// Error Handlingreturn;} rollback = 1; // CreateEvent succeeded Wait = CreateThreadpoolWait((PTP_WAIT_CALLBACK) MyWaitCallback,NULL,NULL); if(NULL == Wait) {_tprintf(_T("CreateThreadpoolWait failed. LastError: %u\n"),GetLastError());goto new_wait_cleanup;} rollback = 2; // CreateThreadpoolWait succeeded //// Need to re-register the event with the wait object// each time before signaling the event to trigger the// wait callback//for (i = 0; i < 5; i ++) {SetThreadpoolWait(Wait,hEvent,NULL); //將事業設定成觸發態SetEvent(hEvent); //// Delay for the waiter thread to act if necessary//Sleep(500); //// Block here until the callback function is done executing////等待回呼函數執行完WaitForThreadpoolWaitCallbacks(Wait, FALSE);} new_wait_cleanup:switch (rollback) {case 2:// Unregister the wait by setting the event to NULLSetThreadpoolWait(Wait, NULL, NULL); // Close waitCloseThreadpoolWait(Wait); case 1:// Close eventCloseHandle(hEvent); default:break;}return;} int main(){DemoCleanupPersistentWorkTimer(); DemoNewRegisterWait(); return 0;}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.