自终止线程。使用加入或分离

Self terminating thread. Use join or detach

我有一个状态机正在 std::thread 中处理。该状态机初始化网络连接,处理数据,并在收到特定消息后自行关闭。以这种方式使用 join 会触发 'abort() has been called' 异常。这是适合分离线程的情况之一吗?

#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;
}

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

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 表示 "wait for the given thread to finish, then continue on"。您是在告诉一个线程等待它自己完成。所以它只能在已经结束的时候结束,这显然是矛盾的。

应该调用join的地方在ThreadExample的析构函数中。 ThreadFunction 使用 ThreadExample 的成员,并且 ThreadExample 也拥有 std::thread 对象,所以 ThreadExample 不能在线程还在的时候死掉 运行宁。在您显示的代码中,如果您在线程完成之前输入一些内容,您将 运行 陷入该问题:然后 ThreadExample 被销毁,并且其中的 std::thread 对象也随之销毁。如果 std::thread 在可连接时被销毁(即非分离线程仍在 运行ning),则调用 std::terminate
https://en.cppreference.com/w/cpp/thread/thread/%7Ethread