我有一个执行一些繁重任务的函数,所以我想在主线程以外的线程中运行它。代码如下:
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与操作系统交谈。
答案 0 :(得分:1)
你需要让thread.detach()
可中断:在做这些事情时,定期检查一个标志,该标志应该告诉它是继续还是丢弃所有内容并提前退出。
有了这个,当你收到另一个繁重任务的命令时,你首先引发“中断”标志,加入工作线程以确保它“死亡”(所以,没有{先前{1}}然后启动新的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();
}
}
}