首页 > 解决方案 > 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.

大多数时候这工作得很好,但这个断言时不时地失败。在考虑了一段时间之后,我有一些我认为可行的理论:

  1. 在线程执行开始时直接调用get_id()可能会出现问题(可能是 boost 内部的某种竞争条件)
  2. doStart在执行和赋值之间存在竞争条件,m_thread因此有时会doStart在未初始化m_thread变量被赋值之前访问它
  3. 的赋值m_thread格式错误,因为它可能无意中调用了线程对象的复制构造函数(这可能会改变 ID)

从这些可能性中,我认为 2) 是最有可能的。如果是这种情况,我的问题是:根据我的发现,我无法将线程分配给m_thread然后启动它。因此我无法确保在新线程中运行m_thread之前已经初始化。doStart

我能想出的唯一解决方案是引入一个额外的成员变量std::atomic<bool>,该变量已初始化false并且仅在分配true 后才设置为。 m_threaddoStart验证线程 ID 之前,我会在该条件下执行主动等待。不过,这对我来说似乎不是很吸引人。有更好的方法吗?

标签: c++multithreadingboost

解决方案


推荐阅读