自终止线程。使用联接或分离

时间:2019-08-23 11:17:34

标签: c++ multithreading join detach

我有一个状态机正在std :: thread中处理。此状态机初始化网络连接,处理数据,并且在收到特定消息后需要关闭自身。以这种方式使用join会触发“ abort()已被调用”异常。这是分离线程合适的情况之一。

#include <iostream>

#include <thread>
#include <atomic>
#include <memory>

class ThreadExample
{
public:
    ThreadExample()
    {
        StartThread();
    }

    void StartThread()
    {
        //start thread;
        run_thread = true;
        the_thread = std::thread(&ThreadExample::ThreadFunction, this);
    }

    void ThreadFunction()
    {
        while (run_thread)
        {
            if (correct_message_found)
                ShutdownThread();
            else
                ProcessMessage();   //example code to imitate network processing

            //arbitrary wait. not relevant to the problem
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
    }

    //read in by some network connection
    void ProcessMessage(/*some message data*/)
    {
        static int counter = 0;
        if (counter == 3)
        {
            correct_message_found = true;
        }
        else
        {
            std::cout << "Waiting for the right message\n";
            counter++;
        }
    }

    void ShutdownThread()
    {
        run_thread = false;
        if (the_thread.joinable())
            the_thread.join();
    }

private:
    std::thread the_thread;
    std::atomic_bool run_thread;
    bool correct_message_found = false;
};

int main()
{
    auto example = std::make_unique<ThreadExample>();

    int data;
    std::cin >> data;
}

1 个答案:

答案 0 :(得分:4)

从内部终止线程的正确方法是简单地从线程正在执行的函数中返回:

void ThreadFunction()
{
    while (run_thread)
    {
        if (correct_message_found)
            return;
        else
            ProcessMessage();   //example code to imitate network processing

        //arbitrary wait. not relevant to the problem
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

从应该连接的线程中调用join是错误,请参阅第一个错误条件:https://en.cppreference.com/w/cpp/thread/thread/join

join的意思是“等待给定线程完成,然后继续”。您在告诉线程要等到它本身完成为止。因此,它只有在结束后才能结束,这显然是矛盾的。

调用join的地方ThreadExample的析构函数中。 ThreadFunction使用ThreadExample的成员,并且ThreadExample也拥有std::thread对象,因此在线程仍在运行时,不允许ThreadExample死亡。在显示的代码中,如果您在线程完成之前输入了某些内容,就会遇到该问题:ThreadExample被销毁,并且std::thread对象也生活在其中。如果std::thread在可连接时被破坏(即,非分离线程仍在运行),则称为std::terminate
https://en.cppreference.com/w/cpp/thread/thread/%7Ethread