c++ - 可从外部停止的 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>
隐式删除的目的是什么,为什么在这里很重要?另外:我还应该使用什么(而不是互斥锁)?
解决方案
std::thread([quit, doit]()
暂时先把编译错误放在一边:这说明这个 lambda通过 valuedoit
捕获了这个变量。因此,即使编译错误神奇地消失了,最终结果也将是完全无用且永远无法工作的东西。lambda 所做的就是一遍又一遍地检查其捕获的对象,这是一个与“真实”对象完全不同且独立的对象(毕竟这就是 lambda按值捕获的工作方式),其他人都不会设置,直到时间结束。doit
doit
如果doit
是全局对象,则不需要捕获它。如果不是,如果它具有本地范围,则 lambda 应通过引用捕获它(使用&
前面的 -thingy)。然后您必须以某种形式或方式确保本地范围不会终止,直到该执行线程停止,或者至少(以某种方式)它将不再在逻辑上访问通过引用捕获的对象,因此它可以在其原始范围内被销毁。
推荐阅读
- reactjs - 即使卸载了 React 函数组件,我如何保持它的值
- php - Laravel Mime Check 内存不足
- sql - 如何在更改 PostgreSQL 表中的列顺序时保持序列完整性?
- javascript - 如何在 Svelte 中创建派生变量?
- optaplanner - Solver.solve() 返回看似随机的解决方案和分数,而不是最好的
- r - 过滤具有不匹配变量值的重复行.in R
- sql - 带有 json_agg 并在嵌套聚合中使用计数的嵌套对象数组
- python - 将 for 循环中的数据打印到 Pandas DataFrame 中
- google-cloud-platform - 云函数权限问题
- python - 处理“地图”对象的最佳方法是不可下标的