在使用事件进行多线程的同步时,栈里面创建事件对象后,还需要通过closehandle()删除它吗?
HANDLE Hevent = NULL;
void a::OnButtonStartTHREAD()
{
   waitforSingleObject(hEvent,INFINITE);
   ...
   SetEvent(hEvent);
}

解决方案 »

  1.   

    当然要,栈里面存放的只是HANDLE对象空间,及存放的仅仅是一个指针的空间,而HANDLE所申请的空间都在堆中,不close是不会自动释放的。
      

  2.   

    当你新建一个事件对象时,系统会做两件事:
    1、在内核空间中创建事件内核对象。
    2、在进程的内核对象句柄表中,建立到该对象的引用。即:操作系统拥有内核对象,进程拥有对象的句柄,而线程则必须通过系统API来访问句柄所标识的内核对象。栈中存放的只是句柄的值,退栈并不会自动释放对象。所以,当不再需要该对象时,必须手动释放!
      

  3.   

    在windows多进程demo:mfc_advanced_mtrecalc中,Microsoft的作者使用了5个事件句柄,我在原代码中搜索CloseHandle,竟然一个也没有搜索到!看来,Event句柄和其他内核对象的句柄的行为有可能不同呀。
    这是部分原代码:
    CRecalcDoc::CRecalcDoc()
    {
    m_nInt1 = m_nInt2 = m_nSum = 0;
    m_bRecalcNeeded = m_bRecalcInProgress = FALSE;
    m_nRecalcSpeedSeconds = 5; m_nCurrentDemoCommand = ID_SINGLE_THREAD; m_hEventStartRecalc = CreateEvent(NULL, FALSE, FALSE, NULL); // auto reset, initially reset
    m_hEventRecalcDone = CreateEvent(NULL, TRUE, TRUE, NULL); // manual reset, initially set
    m_hEventKillRecalcThread = CreateEvent(NULL, FALSE, FALSE, NULL); // auto reset, initially reset
    m_hEventRecalcThreadKilled = CreateEvent(NULL, FALSE, FALSE, NULL); // auto reset, initially reset m_recalcThreadInfo.m_hEventStartRecalc = m_hEventStartRecalc;
    m_recalcThreadInfo.m_hEventRecalcDone = m_hEventRecalcDone;
    m_recalcThreadInfo.m_hEventKillRecalcThread = m_hEventKillRecalcThread;
    m_recalcThreadInfo.m_hEventRecalcThreadKilled = m_hEventRecalcThreadKilled; m_pRecalcWorkerThread = NULL;
    }CRecalcDoc::~CRecalcDoc()
    {
    // In this application, the document owns the worker thread.
    // The document's destructor is responsible for killing the active worker
    // thread. // It's a good idea to wait for the worker thread to notify via a
    // "thread killed" event that it has killed itself. Otherwise, in the case
    // where the app is terminating, is possible (even if unlikely) that it
    // will detect a memory leak of the CWinThread object before the
    // CWinThread object has had a chance to auto-delete itself. DWORD dwExitCode;
    if (m_pRecalcWorkerThread != NULL &&
    GetExitCodeThread(m_pRecalcWorkerThread->m_hThread, &dwExitCode) &&
    dwExitCode == STILL_ACTIVE)
    {
    // Kill the worker thread by setting the "kill thread" event.
    // See comment in OnKillWorkerThread for explanation of the sequence
    // of the "kill thread" and "start recalc" events.
    SetEvent(m_hEventKillRecalcThread);
    SetEvent(m_hEventStartRecalc);
    WaitForSingleObject(m_hEventRecalcThreadKilled, INFINITE);
    }
    }
      

  4.   

    只要你打开或创建了任何一种内核对象,你都应该自己负责释放句柄。当然,进程退出时系统也会帮你做这件事(那个Demo可能就是这样干的),不过这并不是好的编程风格,而且还可能造成泄露
      

  5.   

    sure.如果你觉得这个不好控制,就用CEvent类。