重用线程-Boost与STD线程行为

时间:2018-11-29 04:21:21

标签: c++ multithreading boost pthreads

我似乎在boost和std线程之间得到了不同的线程对象分配行为。如果我使用增强线程,则可以重新分配线程成员变量并重新创建线程。如果我使用标准线程,则会收到运行时错误terminate called without an active exception

这里是有问题的代码(运行,然后将std ::替换为boost ::)

class ThreadTest 
 {
    private:
    std::thread mythread;
    std::atomic<bool> running_;

    int doSomeWork(){
        int i=0;
        cout << "starting" << endl;
        while(running_){
            cout << "working" << endl;
            std::this_thread::sleep_for (std::chrono::seconds(1));
            if (i>3){ break; } else { i++; }
        }
        running_ = false;
    }

    public:
    void runThread(){
        running_ = true;
        mythread = std::thread(&ThreadTest::doSomeWork, this);
    }

    void joinThread(){
        mythread.join();
    }
 };

int main(){ 
    ThreadTest test;
    test.runThread();
    std::this_thread::sleep_for (std::chrono::seconds(10));
    test.runThread();
    test.joinThread();
    return 0;
 }

增强输出:

starting
working
working
working
working
working
starting
working
working
working
working
working

std的输出::

starting
working
working
working
working
working
terminate called without an active exception
Aborted (core dumped)

这一段特定的代码在一个似乎没有增强依赖关系的库中使用。我想保持这种状态,那么有没有办法使用std线程获得增强的“重新分配”行为?

编辑-解决方案

我向在线程函数std::atomic<bool> threadInitialized_;中设置为true的类中添加了doSomeWork()。我的runThread()方法变为:

void runThread(){
    if(threadInitialized_)
       mythread.join();

    running_ = true;
    mythread = std::thread(&ThreadTest::doSomeWork, this);
}

我知道这将阻塞主线程,直到生成线程为止。

3 个答案:

答案 0 :(得分:1)

来自std::thread::operator = ()

“如果[线程对象]是可连接的,则调用Terminate()。”

答案 1 :(得分:1)

通常,正如上面正确指出的那样,所有(可连接)线程都需要在销毁对象之前进行连接或分离。

现在,Boost线程与std :: thread之间的(众多)区别之一是Boost线程将自己分离到其析构函数中,而std :: thread则没有。您对std :: thread的不正确使用会因此正确触发Terminate()。

PS:不要(!!)相信std :: threads和boost :: thread上方的其他评论者应该表现出“相同”的感觉-这不是真的!

答案 2 :(得分:1)

在使用boost :: thread时,如果您未显式调用join()或detach(),则boost :: thread析构函数和赋值运算符将分别对要销毁/分配给该线程的对象调用detach()。 对于C ++ 11 std :: thread对象,这将导致对std :: terminate()的调用并中止应用程序。在这种情况下,您必须手动调用detach()或join()。