【发布时间】:2011-10-27 19:34:32
【问题描述】:
我创建了一个自定义ThreadPool,它使用_beginthreadex() 启动了许多win32 线程。线程正在运行一个简单的循环,试图从阻塞队列中取出任务,但有时我需要停止线程,如果它们在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) 两次)?此外,还有比这更好的方法吗?
【问题讨论】:
标签: c++ multithreading winapi concurrency