我有一个状态机正在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;
}
答案 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