继这个问题之后,我想知道我们应该采取什么推荐方法来替换遗留代码中非常常见的模式。
我们有很多地方,主线程正在生成一个或多个后台工作线程,并使用适当同步的队列定期抽出一些工作让他们去做。因此,工作线程的一般模式如下所示:
会有一个事件HANDLE
并在bool
某处定义(通常作为成员变量) -
HANDLE hDoSomething = CreateEvent(NULL, FALSE, FALSE, NULL);
volatile bool bEndThread = false;
然后工作线程函数在工作之前等待事件发出信号,但会检查主循环内的终止请求 -
unsigned int ThreadFunc(void *pParam)
{
// typical legacy implementation of a worker thread
while (true)
{
// wait for event
WaitForSingleObject(hDoSomething, INFINITE);
// check for termination request
if (bEndThread) break;
// ... do background work ...
}
// normal termination
return 0;
}
然后主线程可以像这样给后台线程一些工作 -
// ... put some work on a synchronized queue ...
// pulse worker thread to do the work
SetEvent(hDoSomething);
它最终可以像这样终止工作线程 -
// to terminate the worker thread
bEndThread = true;
SetEvent(hDoSomething);
// wait for worker thread to die
WaitForSingleObject(hWorkerThreadHandle, dwSomeSuitableTimeOut);
在某些情况下,我们使用了两个事件(一个用于工作,一个用于终止)WaitForMultipleObjects
,但一般模式是相同的。
所以,看看用volatile bool
C++11 标准等效替换,是不是就像替换这个一样简单
volatile bool bEndThread = false;
有了这个?
std::atomic<bool> bEndThread = false;
我确信它会起作用,但似乎还不够。此外,它不会影响我们使用两个事件和 no 的情况bool
。
请注意,我不打算用PPL和/或并发运行时等价物替换所有这些遗留的东西,因为虽然我们将它们用于新的开发,但遗留的代码库已经结束,只需要与最新的开发兼容工具(我上面链接的原始问题显示了我担心的地方)。
有人可以给我一个粗略的 C++11 标准代码示例,我们可以将其用于这种简单的线程管理模式来重写我们的遗留代码而无需过多重构?