对于一个分离线程,我们无法使用 joinable()
函数,使用布尔变量似乎也不是正确的方式。有没有一种方法可以检查分离线程是否仍然活着并正在运行?
对于一个分离线程,我们无法使用 joinable()
函数,使用布尔变量似乎也不是正确的方式。有没有一种方法可以检查分离线程是否仍然活着并正在运行?
有几种方法可以解决这个问题。如果您坚持使用线程,则可以使用std::future<void>
来检测其何时退出:
std::promise<void> promised_thread_exit;
std::future<void> thread_exited = promised_thread_exit.get_future();
std::thread(
[] (std::promise<void> promised_thread_exit)
{
promised_thread_exit.set_value_at_thread_exit();
DoBackgroundWork();
},
std::move(promised_thread_exit));
thread.detach();
// later...
thread_exited.get();
然而,这似乎是很多工作。 std::thread
是一种相当底层的原语。 如果目标只是在后台执行一些工作,则 std::async
是更好的选择:
std::future<void> work_complete = std::async(std::launch::async, DoBackgroundWork());
// later...
work_complete.get();
无论哪种情况,如果您需要在不阻塞的情况下检查工作状态,可以通过等待超时为0的future
来实现:
using namespace std::chrono_literals;
//...
if (work_complete.wait_for(0s) == std::future_status::ready)
{
// work has finished
}
话虽如此,像这样检查状态通常是不必要的。如果看起来需要,那么您应该考虑是否有更简单的替代方案。
thread::join
一样。问题在于如何检查工作是否已经完成,而不是等待工作完成。 - n. m.std::future
进行非阻塞检查,等待超时为0。 (在未来 - 没有双关语 - 我们将拥有is_ready
方法。)但一般来说,我们只有两个原因想要检查线程是否完成:(1)查看结果是否准备好以便我们可以使用它,或者(2)在取消后进行清理。 std :: future
很好地处理了这两种情况。 - Peter Rudermanstd::condition_variable
来在分离的线程完成时通知主线程:#include <iostream>
#include <mutex>
#include <thread>
int main()
{
std::mutex mutex;
std::condition_variable cv;
std::thread t([&]() {
std::cout << "Wait" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock(mutex);
std::cout << "Thread end" << std::endl;
cv.notify_all();
});
t.detach();
std::unique_lock<std::mutex> lock(mutex);
cv.wait(lock);
std::cout << "Main end" << std::endl;
return 0;
}
const_cast
。 - user7860670