問題代碼: 1 #include<windows.h> 2 #include<iostream> 3 #include<thread> 4 HANDLE h1; 5 HANDLE h2; 6 7 void CALLBACK test(PVOID a, BOOLEAN b) 8 { 9 std::co ...
問題代碼:
1 #include<windows.h> 2 #include<iostream> 3 #include<thread> 4 HANDLE h1; 5 HANDLE h2; 6 7 void CALLBACK test(PVOID a, BOOLEAN b) 8 { 9 std::cout << "This a test function excuted by Thread:" << std::this_thread::get_id()<< std::endl; 10 //std::cout << "Here we try to delete timer in Thread:" << std::this_thread::get_id() << std::endl; 11 if (0 == DeleteTimerQueueTimer(NULL, h1, INVALID_HANDLE_VALUE)) 12 { 13 std::cout << "Timer Deleted Failed in Thread:" << std::this_thread::get_id() << std::endl; 14 } 15 std::cout << "Timer Deleted Successfully in Thread:" << std::this_thread::get_id() << std::endl; 16 17 } 18 void CALLBACK test1(PVOID l, BOOLEAN t) 19 { 20 std::cout << "This a test1 function excuted by Thread:" << std::this_thread::get_id() << std::endl; 21 } 22 23 int main() 24 { 25 26 std::cout << "******This is a Test for TimeQueueTimer in Windows API******" << std::endl; 27 std::cout << "Main thread is executed by thread: " << std::this_thread::get_id() << std::endl; 28 //test(PVOID(1), TRUE); 29 try 30 { 31 CreateTimerQueueTimer(&h1, NULL, WAITORTIMERCALLBACK(test), NULL, 0, 1000, WT_EXECUTEINTIMERTHREAD); 32 //Sleep(1000); 33 34 CreateTimerQueueTimer(&h2, NULL, WAITORTIMERCALLBACK(test1), NULL, 0, 1000, WT_EXECUTEINTIMERTHREAD); 35 36 37 //CreateTimerQueueTimer(&h1, NULL, [](PVOID lpParameter, BOOLEAN TimerOrWaitFired) { 38 // test(lpParameter, TimerOrWaitFired); // Call your original test function from within the lambda 39 // }, NULL, 0, 1000, WT_EXECUTEINTIMERTHREAD); 40 41 } 42 catch (const std::exception& e) 43 { 44 std::cout << "something error with the timer: " << e.what() << std::endl; 45 } 46 47 48 if (std::cin.get()) 49 { 50 if (0 == DeleteTimerQueueTimer(NULL, h2, INVALID_HANDLE_VALUE)) 51 { 52 std::cout << "Timer Deleted Failed in Thread:" << std::this_thread::get_id() << std::endl; 53 } 54 std::cout << "Timer Deleted Successfully in Thread:" << std::this_thread::get_id() << std::endl; 55 56 }; 57 Sleep(1000); 58 59 return 0; 60 }
Main()函數中test1回調無法執行!
問題分析:
CreateTimerQueueTimer和DeleteTimerQueueTimer 分別負責線程的開啟和中止,函數定義如下:
BOOL CreateTimerQueueTimer( [out] PHANDLE phNewTimer, [in, optional] HANDLE TimerQueue, [in] WAITORTIMERCALLBACK Callback, [in, optional] PVOID Parameter, [in] DWORD DueTime, [in] DWORD Period, [in] ULONG Flags );
BOOL DeleteTimerQueueTimer( [in, optional] HANDLE TimerQueue, [in] HANDLE Timer, [in, optional] HANDLE CompletionEvent );
主線程中分別利用CreateTimerQueueTimer開啟後臺線程調用回調test()和test1(),併在test()調用中結束調用。由於DeleteTimerQueueTimer中CompletionEvent中使用的是INVALID_HANDLE_VALUE,導致線程會等待所有timer線程執行結束,才能返回。而當前執行回調的線程等不到自己結束,陷入死鎖。因為CreateTimerQueueTimer的Flag參數使用的是WT_EXECUTEINTIMERTHREAD,導致test1回調和test使用的是同一線程,而test線程已經死鎖,所以test1也無法得到執行
解決方案:
- 不應該在回調中調用DeleteTimerQueueTimer中止線程
- 如果必須在回調中中止線程,CompletionEvent應設為NULL,標記當前線程結束後,直接返回0(執行失敗),回調執行完,不再繼續執行
- CreateTimerQueueTimer使用Flag WT_EXECUTEDEFAULT開啟新線程,即使上一個timer線程死鎖,第二個線程仍可以執行
翻譯
搜索
複製