Kir*_*ril 5 c++ concurrency winapi multithreading
我创建了一个自定义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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的想法是将相同数量的特殊任务排队(让我们称之为"终止任务"),因为池中有线程,每个"终止任务"都会调用_endthreadex(0)以退出线程.如果阻塞队列中还有其他任务,那么我真的不在乎,因为只要我将某个任务出列,我就会运行它并检查该_running标志以确定该线程是否需要将任何更多任务出列.
void TerminationTask::Run()
{
_endthreadex(0);
}
Run Code Online (Sandbox Code Playgroud)
我对这种方法有几点顾虑; 主要是,如果我处理了一个非终止任务并且_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);
}
Run Code Online (Sandbox Code Playgroud)
这是否会导致与我的冲突TerminationTask或线程在执行后直接退出循环TerminationTask::Run()(即它不会调用_endthreadex(0)两次)?此外,还有比这更好的方法吗?
_endthreadex(0)在线程方法结束时调用很好.它也是可选的.如果你只是正常地离开线程方法,那么_endthreadex(0)就会为你调用.
您可以显式调用_endthread或_endthreadex来终止线程; 但是,当线程从作为参数传递的例程返回到_beginthread或_beginthreadex时,会自动调用_endthread或_endthreadex.REF
发送终止任务是获取阻塞线程池线程以解除阻止和退出的正确方法.
所以,总结一下:
TerminationTask::Run是正确的._endthreadex(0)最后ThreadPool::Loop.