WaitForMultipleObjects не возвращает управление
От: Аноним  
Дата: 20.05.08 07:34
Оценка:
Создаю несколько потоков и в деструкторе класса ожидаю их завершения.

Данный фрагмент отрабатывает в деструкторе. Для каждого потока сигналим событие и ожидаем завершения.

    DWORD size  = (DWORD)m_listPool.size();
    DbgPrintF(_T("Thread pool size: %d. \n"), size);
    PHANDLE handles = (PHANDLE)new HANDLE[size];
    if(!handles)
    {
        return;
    }
    
    for(it = m_listPool.begin(), i = 0; it != m_listPool.end(); it++, i++)
    {
        handles[i] = it->hThread;
        DbgPrintF(_T("Signal %d. \n"), i);
        SetEvent(it->hStopEvent);
    }
    m_csPoolGuard.Unlock();

    DbgPrintF(_T("Before wait!!! \n"));
    WaitForMultipleObjects(size, handles, TRUE, INFINITE);
    DbgPrintF(_T("After wait!!! \n"));

    m_csPoolGuard.Lock();
    for(it = m_listPool.begin(); it != m_listPool.end(); it++)
    {
        if(it->hStopEvent)
        {
            CloseHandle(it->hStopEvent);
            it->hStopEvent = NULL;
        }
        if(it->hWorkEvent)
        {
            CloseHandle(it->hWorkEvent);
            it->hWorkEvent = NULL;
        }
        if(it->hThread)
        {
            CloseHandle(it->hThread);
            it->hThread = NULL;
        }
    }
    m_listPool.erase(m_listPool.begin(), m_listPool.end());
    m_csPoolGuard.Unlock();

    delete [] handles;


Функция потока получает событие и завершается.


// it - итератор на элемент списка, содержащего хэндлы событий и потока 
for(;;)
    {
        dwRes  = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
        switch(dwRes - WAIT_OBJECT_0)
        {
        case 0:
                        // получаем событие
            DbgPrintF(_T("Finish. \n"));
            goto FINISH;

        // выполняем зачистку
        m_csPoolGuard.Lock();
    CloseHandle(it->hWorkEvent);
    it->hWorkEvent = NULL;
    CloseHandle(it->hStopEvent);
    it->hStopEvent = NULL;
    /*CloseHandle(it->hThread);
    it->hThread = NULL;*/
    m_listPool.erase(it);
    m_csPoolGuard.Unlock();


Если CloseHandle(it->hThread) раскомментрировать, то WaitForMultipleObjects срабатыает тогда, когда один из потоков еще продолжает выполнениею. Если нет, мы не выходим из WaitForMultipleObjects.
Отладочный вывод при закомментированом CloseHandle(it->hThread) следующий:

Thread pool size: 3.
Signal 0.
Finish.
Signal 1.
Finish.
Signal 2.
Finish.
Thread quit!!!
Thread quit!!!
Thread quit!!!
Before wait!!!

Как видно, события пробудили потоки, потоки закончили выполнение, но по прежнему ждем на WaitForMultipleObjects. Из-за чего это может быть?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.