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. Из-за чего это может быть?
Re: WaitForMultipleObjects не возвращает управление
От: Аноним  
Дата: 20.05.08 07:40
Оценка:
DllMain?
Re[2]: WaitForMultipleObjects не возвращает управление
От: Аноним  
Дата: 20.05.08 07:43
Оценка:
Здравствуйте, Аноним, Вы писали:

А>DllMain?


Можно поподробнее насчет DllMain
Re: WaitForMultipleObjects не возвращает управление
От: ovl123 Россия  
Дата: 20.05.08 07:52
Оценка:
После посылки сигнала потоку, я ожидаю его завершения вот таким образом.

while(1)//цикл ожидания завершения работы
{
DWORD lpExitCode;
BOOL Result=GetExitCodeThread(
WorkThreadHandle, // handle to the thread
&lpExitCode // termination status
);
if(!Result)
break;
if(lpExitCode!=STILL_ACTIVE)
break;
Sleep(150);
}



Здравствуйте, Аноним, Вы писали:

А>Создаю несколько потоков и в деструкторе класса ожидаю их завершения.


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

А>

А>    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. Из-за чего это может быть?
Re[3]: WaitForMultipleObjects не возвращает управление
От: Аноним  
Дата: 20.05.08 07:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>DllMain?


А>Можно поподробнее насчет DllMain


// Код DllMain выглядит вот так

BOOL APIENTRY DllMain( HANDLE hModule, 
                      DWORD  ul_reason_for_call, 
                      LPVOID lpReserved
                      )
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
            GenericTdiManager::ProcessAttach();
            break;
        case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            break;
        case DLL_PROCESS_DETACH:
            GenericTdiManager::ProcessDetach();
            break;
    }
    return TRUE;
}

void GenericTdiManager::ProcessAttach()
{
    GenericTdiManager * pInst = GetInstance();
    if ( pInst )
    {
        SyncObject obj(&pInst->m_Mutex);
        pInst->m_dwRefCounter++;
    }
}

void GenericTdiManager::ProcessDetach()
{
    bool bStop = false;
    GenericTdiManager * pInst = GetInstance();
    if ( pInst )
    {
        {
            SyncObject obj(&pInst->m_Mutex);
            if ( pInst->m_dwRefCounter > 0 )
            {
                pInst->m_dwRefCounter--;
                if ( pInst->m_dwRefCounter == 0 )
                {
                    if ( pInst->m_dwStartRefCounter > 0 )
                    {
                        pInst->m_dwStartRefCounter = 0;
                        bStop = true;
                    }
                    pInst->RemoveTrace();
                }
            }
        }
        if ( bStop )
        {
            pInst->m_generic.StopDriver();
        }
    }
}
Re[3]: WaitForMultipleObjects не возвращает управление
От: IID Россия  
Дата: 20.05.08 07:53
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>DllMain?


А>Можно поподробнее насчет DllMain


в поиск! Ожидание в DllMain.
kalsarikännit
Re[3]: WaitForMultipleObjects не возвращает управление
От: Аноним  
Дата: 20.05.08 08:20
Оценка:
А>Можно поподробнее насчет DllMain
В DllMain нельзя ждать начала и завершения выполнения потоков. Кстати конструкторы и деструкторы статических объектов в dll неявно выполняются в DllMain.
Re[4]: WaitForMultipleObjects не возвращает управление
От: Аноним  
Дата: 20.05.08 08:27
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>Можно поподробнее насчет DllMain

А>В DllMain нельзя ждать начала и завершения выполнения потоков. Кстати конструкторы и деструкторы статических объектов в dll неявно выполняются в DllMain.

А что произойдет, если в DllMain будет ожидание завершения потока. Что приводит к dead lock?
Re[5]: WaitForMultipleObjects не возвращает управление
От: Аноним  
Дата: 20.05.08 10:10
Оценка:
А>А что произойдет, если в DllMain будет ожидание завершения потока. Что приводит к dead lock?
PEB lock
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.