c++多线程:一次只保持一个线程(除了主线程)活动



我有一个函数做一些繁重的任务,所以我想在主线程以外的线程中运行它。代码如下所示:

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();
        }
    }
}

最新更新