我有一个函数做一些繁重的任务,所以我想在主线程以外的线程中运行它。代码如下所示:
Data global_data;
void heavy_task() {
...//update global_data
}
void main() {
while (True) {
if (user_press_w) {
std::thread t(heavy_task);
t.detach();
}
}
}
如何修改代码,使一次只有一个线程在运行?例如,如果用户按w启动一个线程,然后在第一个带有heavy_task的线程完成之前,她再次按w,第一个线程将停止,第二个线程开始运行。这在用户持续按键的情况下也很有帮助,在这种情况下,只有由最后一次键检测触发的线程保持存活。
----------------- 解决方案 -------------------
我已经按照Adrian Colomitchi的建议修改了我的代码,
std::shared_ptr<std::thread> my_thread;
bool should_terminate = false;
Data global_data;
void heavy_task() {
// This function actually does its work in a loop
// so I check should_terminate at each iteration
while (...) {
...
if (should_terminate) return;
}
}
void main() {
while (True) {
if (user_press_w) {
should_terminate = true;
if (my_thread!= nullptr && my_thread->joinable())
my_thread->join();
my_thread= std::make_shared<thread>(heavy_task);
should_terminate = false;
}
}
}
--------------- 这种情况 -------------------
我正在写一个交互式光线追踪程序。世界首先由OpenGL应用程序绘制,用户在世界中导航,选择一个满意的视点,按下一个键开始光线追踪。在光线跟踪完成之前,用户可以改变视点并按下键开始新的光线跟踪。我使用glfw与操作系统对话
您需要使heavy_task
可中断:在做这些事情时,定期检查一个标志,它应该告诉它是继续还是放弃所有内容并过早退出。
有了这个,当你收到另一个繁重任务的命令时,你首先提出"中断"标志,加入工作线程以确保它"死亡"(所以,之前没有thread.detach()
),然后启动新的heavy_task
。
以下行:
Data global_data;
void heavy_task(bool& shouldStop) {
while(! ready && ! shouldStop) {
// update **some** global data, in as small slices as you can afford
}
}
void main() {
bool interruptWThread=false;
std::shared_ptr<std::thread> thread;
while (True) {
if (user_press_w) {
if(thread) {
interruptWThread=true;
thread->join(); // wait here until thread exit is confirmed
interruptWThread=false;
}
thread = std::make_shared<std::thread>(
[& interruptWThread]->heavy_task(interruptWThread)
);
// nope!! Never detach a thread you may still need later
// t.detach();
}
}
}