c++ - Boost线程:在**构造之后启动线程(不在构造函数中)
问题描述
在我的代码中,我想(至少在调试版本中)确保某些函数只在特定线程中执行。更具体地考虑以下类:
class MyClass {
private:
boost::thread m_thread;
void doStart();
public:
void start();
};
的实现start
是
void MyClass::start() {
m_thread = boost::thread(&MyClass::doStart, this);
}
又名:它创建一个新线程并在该新线程中执行doStart
函数。此外,它将这个新线程存储在成员变量中。
在开始时doStart
检查它正在执行的线程:
void MyClass::doStart() {
assert(m_thread.get_id() == boost::this_thread::get_id());
}
这应该确保doStart
只会在类自己的工作线程中运行,存储在m_thread
.
大多数时候这工作得很好,但这个断言时不时地失败。在考虑了一段时间之后,我有一些我认为可行的理论:
- 在线程执行开始时直接调用
get_id()
可能会出现问题(可能是 boost 内部的某种竞争条件) doStart
在执行和赋值之间存在竞争条件,m_thread
因此有时会doStart
在未初始化m_thread
变量被赋值之前访问它- 的赋值
m_thread
格式错误,因为它可能无意中调用了线程对象的复制构造函数(这可能会改变 ID)
从这些可能性中,我认为 2) 是最有可能的。如果是这种情况,我的问题是:根据我的发现,我无法将线程分配给m_thread
然后启动它。因此我无法确保在新线程中运行m_thread
之前已经初始化。doStart
我能想出的唯一解决方案是引入一个额外的成员变量std::atomic<bool>
,该变量已初始化false
并且仅在分配true
后才设置为。 m_thread
在doStart
验证线程 ID 之前,我会在该条件下执行主动等待。不过,这对我来说似乎不是很吸引人。有更好的方法吗?
解决方案
推荐阅读
- python - 如何通过 os.system() 调用 anaconda 环境以从其他 python(3.7) 脚本运行特定的 python(2.7) 包?
- django - 如何将对象从选择控件传递到django中的另一个视图
- javascript - PHP区分javascript和用户点击?
- python - 当使用 spyder 3.3.3 和 ipython 7.4 时,来自 PyQt5 的 app.exec 阻止了代码
- docker - 尽管存在 sudo,但 Packer 使我的 docker 构建失败并出现错误“sudo:未找到”
- swift - 禁用相机视图增长动画
- elasticsearch - ElasticSearch 可以接受预标记的内容并返回相应的 tf-idf 分数吗?
- java - 并行流看起来不像完全并行工作
- html - 下拉菜单在网站上不起作用(css 显示标签)
- c - 使用递归函数向后打印给定的字符串,而不使用