Как остановить блокирующий поток win32?

Я создал собственный ThreadPool , который запускает несколько потоков win32 с помощью _beginthreadex () . Потоки выполняют простой цикл, который пытается удалить задачи из очереди блокировки, но иногда мне нужно остановить потоки, и если они заблокированы на Dequeue , я не знаю, как получить потоки из этого состояния блокировки.

void ThreadPool::Loop()
{
    while(_running)
    {
        try
        {
            // Attempts to dequeue a task and run it
            _taskQueue.Dequeue()->Run();
        }
        catch(BlockingQueueTerminate&)
        {
            // Eat the exception and check the running flag
            continue;
        }
    }
}

Моя идея заключалась в том, чтобы поставить в очередь такое же количество специальных задач (назовем их «задачами завершения»), сколько потоков в пуле, и каждая «задача завершения» будет вызывать _endthreadex (0) по порядку чтобы выйти из потока. Если в очереди блокировки есть другие задачи, то мне все равно, потому что, как только я удалю задачу из очереди, я ее запускаю и проверю флаг _running , чтобы определить, нужно ли потоку исключить из очереди еще какие-либо задачи.

void TerminationTask::Run()
{
    _endthreadex(0);
}

У меня есть несколько опасений по поводу этого подхода; в основном, если я обработал непрерывающуюся задачу и для флага _running установлено значение false , то мой поток не будет вызывать _endthreadex (0) при выходе петля.Мне было интересно, могу ли я вызвать _endthreadex (0) в конце цикла следующим образом:

void ThreadPool::Loop()
{
    while(_running)
    {
        try
        {
            // Attempts to dequeue a task and run it
            _taskQueue.Dequeue()->Run();
        }
        catch(BlockingQueueTerminate&)
        {
            // Eat the exception and check the running flag
            continue;
        }
    }
    _endthreadex(0);
}

Это вызовет конфликт с моей TerminationTask или поток выйдет из цикла непосредственно после выполнения TerminationTask :: Run () (т.е. он не будет вызывать _endthreadex (0) дважды)? Кроме того, есть ли лучший подход, чем этот?

5
задан Kiril 27 October 2011 в 19:34
поделиться