有关如何使 OP 的问题线程安全的直接说明,请阅读第一段。其余部分描述了执行退出条件的另一种方法。
是的,您可以在代码中安全地使用while(mRun)。为了使您现有的示例线程安全调用mthread.join(),以便线程在线程仍在运行时不会执行其析构函数。
控制线程执行的另一种方法是使用异常和异常处理程序来逃避线程循环。这是通过在循环外使用 try catch 语句来完成的。这是boost::thread 使用的方法所以在你的方法中你会调用my_thread.interrupt_check() 这会抛出一个异常。这将允许展开堆栈并销毁堆栈上的任何对象。但是你必须小心使用这种方法。如果线程中没有捕获到异常,程序将调用std::terminate 并且您的整个程序将停止。这种方法的一个例子是这样的:
void interrupt_check();
class interruptible_thread
{
private:
static thread_local std::atomic<bool>* interrupt_flag;
friend void interrupt_check();
std::atomic<bool> flag;
std::thread thread_obj;
struct interrupt_exception { };
public:
template<typename _Fn, typename... _Args>
interruptible_thread(_Fn& function, _Args& arguments) :
flag(false),
thread_obj([](std::atomic<bool>* flag_var, _Fn&& function, _Args&& arguments)
{ interrupt_flag = flag_var;
try
{
function(std::forward<_Args>(arguments));
} catch (interrupt_exception& e) { }
},
&interrupt_flag,
std::forward<_Fn>(function),
std::forward<_Args>(arguments))
{ }
void interrupt() { flag = true; }
~interruptible_thread() { flag = false; interrupt(); thread_obj.join(); }
}
void interrupt_check()
{
if(!interruptible_thread::interrupt_flag)
throw interruptible_thread::interrupt_exception;
}
这种方法的优点是析构函数可以正确执行,并且可以在调用者希望时终止线程。缺点是如果线程不检查,那么这只是std::thread,开销更大。
还要注意,如果std::thread 对象在线程仍可连接时被销毁,则调用std::terminate。我想这不是将线程包装在对象中的意图。