簡體   English   中英

WaitForSingleObject 問題

[英]WaitForSingleObject problem

首先仔細閱讀問題。

有一個從 CTest class 的 CreateInstance 產生的工作線程。 這是 class 的原型。 hThread 是線程的句柄,hEventShutdown 是用於在程序退出時關閉線程的事件。 WaitForShutdown 是公共的 function ,用於發出 hEventShutdown 信號並等待線程句柄,直到線程正常退出。 WaitForShutdown 從應用程序的退出調用。

//pseudocode
CTest 
{
public:
CTest* CreateInstance();
static threadproc(void *pv);
void WaitForShutdown();

public:
HANDLE hThread;
HANDLE hEventShutdown;

}

void CTest::CTest* CreateInstance()
{
   // spawn a thread, pass 'this' pointer to thread , use beginthreadex 

   hThread = beginthreadex ( threadproc, this );
}


unsigned int CTest::threadproc( void *pv)
{ 

  Ctest *ptest = (Ctest*)pv;

   do
  {
       HANDLES hArray[2] = { pv->hEventShutdown, someotherhandle } 

       dwResult = Waitformultipleobjects( hArrary , 2);

     if ( dwResult == WAIT_OBJECT_0)
        delete pTest; // since it is allocated dynamically ( This is required due to some known reasons in my code)

   if(dwResult == WAIT_OBJECT_0 + 1)
        Doprocessing(); //DoProcessing when other thread signal someotherhandle 

   }while (1)

void   CTest::WaitForShutdown()
{
    SetEvent ( hEventShutdown);

   WaitForSingleObject ( hThread,INFINITE);

}

void CTest::~CTest()
{
   Closehandle(hThread) 
   Closehandle(hEventShutdown);
}

現在如果你仔細看代碼,你會發現事件是從WaitForShutdown function發出的,線程從WaitForMultipleOjbects出來並刪除CTest的指針。 這意味着調用了 CTest 的析構函數,這顯然會關閉線程句柄(hThread)。 但是來自 WaitForShutdown 的 WaitForSingleObject 實際上正在等待線程句柄。 所以這里的行為是不確定的(我想是的,如果我錯了,你可以糾正我)。 另一個問題是當 WaitForSingleObject 正在等待其成員 hThread 時調用了 Ctest 的析構函數,這是不正確的。 我無法從線程中刪除刪除 pTest,因為由於某些原因它必須存在。

您將如何建議解決上述問題?

我能想到的幾個解決方案:

  1. 我可以在另一個 map 中保留線程句柄,但我不想這樣做。
  2. 我可以在 WaitForShutdown 中的 WaitForSingleObject 之前將線程句柄復制到某個局部變量並等待它。 不知道對不對? 你告訴我。
  3. 或者我將使用 Duplicatehandle API 在 WaitForSingleObject 之前獲取現有線程句柄的引用並等待它。 不知道對不對。 不知道在原始的 CloseHandle 之后重復的句柄是否還活着。
  4. 我將保留線程 ID,從線程 ID 獲取線程句柄,並在 WaitForShutdown 中繼續等待線程句柄。 這看起來更優雅,但我不知道有沒有辦法從線程 id 獲取句柄。

糾正我。

感謝您的反饋。

處理此問題的最簡單方法是在WaitForSingleObject返回后從 WaitForShutdown 中刪除線程。 這確保了您需要的所有手柄 - 更重要的是,object 本身 - 一直保持到最后。

我已經按原樣運行了這件作品。 似乎它有效,並且它不會崩潰。 奇怪的是,我們可以在 go 離開WaitforSingleObject(hThread,INFINITE)之前調用CloseHandle(hthread) ) 。 當然,加入線程的“學術”方式首先是WaitForSingleObject(hThread,INFINITE)而不是CloseHandle(hThread) 所以這就是我的建議 - 這樣做。

我不必再添加了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM