首页 > 解决方案 > 可从外部停止的 C++ lambda 线程

问题描述

我正在尝试创建一个辅助线程,如果主线程这么说,它会等待并工作/完成。

像这样的东西:

std::atomic<bool> quit(false), doit(false);

std::thread([quit, doit]()
{
  while (!quit)
  {
    wait();
    if (doit)
      std::cout << "done";
  }
}

编译器说:

1.cpp:26:15: error: call to implicitly-del
eted copy constructor of 'atomic<bool>'
    thread t([quit, doit, ,                   ^~~~~~                      /data/data/com.termux/files/usr/include/c+
+/v1/atomic:1643:7: note: copy constructor of 'atomic<bool>' is implicitly deleted b
ecause base class '__atomic_base<bool>' has a deleted copy constructor                  : public __atomic_base<_Tp>

隐式删除的目的是什么,为什么在这里很重要?另外:我还应该使用什么(而不是互斥锁)?

标签: c++multithreadinglambdaatomic

解决方案


std::thread([quit, doit]()

暂时先把编译错误放在一边:这说明这个 lambda通过 valuedoit捕获了这个变量。因此,即使编译错误神奇地消失了,最终结果也将是完全无用且永远无法工作的东西。lambda 所做的就是一遍又一遍地检查其捕获的对象,这是一个与“真实”对象完全不同且独立的对象(毕竟这就是 lambda按值捕获的工作方式),其他人都不会设置,直到时间结束。doitdoit

如果doit是全局对象,则不需要捕获它。如果不是,如果它具有本地范围,则 lambda 应通过引用捕获它(使用&前面的 -thingy)。然后您必须以某种形式或方式确保本地范围不会终止,直到该执行线程停止,或者至少(以某种方式)它将不再在逻辑上访问通过引用捕获的对象,因此它可以在其原始范围内被销毁。


推荐阅读