首先请仔细阅读问题。

有一个从CTest类的CreateInstance产生的工作线程。这是该类的原型(prototype)。 hThread是线程的句柄,而hEventShutdown是用于在程序退出时关闭线程的事件。 WaitForShutdown是公共(public)函数,用于向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函数发出的信号,线程从WaitForMultipleOjbects中出来,并删除了CTest的指针。这意味着将调用CTest的析构函数,这显然会关闭线程句柄(hThread)。但是,WaitForShutdown中的WaitForSingleObject实际上正在等待线程句柄。因此,这里的行为将是不确定的(我想是的,如果我错了,您可以纠正我)。另一个问题是,当WaitForSingleObject在其成员hThread上等待时,调用Ctest的析构函数是不正确的。由于某些原因,我必须将删除pTest从那里删除,因此我无法将其删除。

您如何建议上述解决方案?

我能想到的几个解决方案:
  • 我可以在另一个映射中保留线程句柄,但我不想这样做。
  • 我可以在WaitForShutdown中的WaitForSingleObject之前将线程句柄复制到某个局部变量,并将在其上等待。不知道这是对的吗?你告诉我。
  • 或者我将使用Duplicatehandle API在WaitForSingleObject之前获取现有线程句柄的引用,然后等待它。不知道这是正确的。不知道在原始的CloseHandle之后重复的句柄是否仍然有效。
  • 我将保留线程ID,从线程ID获取线程句柄,并在WaitForShutdown中继续等待线程句柄。这看起来更优雅,但我不知道有什么方法可以从线程ID获取句柄。

  • 纠正我。

    您的反馈意见表示赞赏。

    最佳答案

    解决此问题的最简单方法是在WaitForSingleObject返回之后,从WaitForShutdown中删除线程。这样可以确保您需要的所有句柄(更重要的是,对象本身)始终保持 Activity 状态。

    09-27 07:35