如何在 C++11 中检查分离线程的状态?

Posted

技术标签:

【中文标题】如何在 C++11 中检查分离线程的状态?【英文标题】:How to check the status of detached thread in C++11? 【发布时间】:2020-01-22 08:59:36 【问题描述】:

我已经尝试了很多方法来寻找解决方案,但到目前为止找不到合适的方法。

我正在使用分离线程,因为我不希望我的主线程等待/阻塞新的子线程,因为它还有许多其他重要的事情要做。

我创建一个线程如下:

std::thread rsync_t(&PreCompile::RunPreCompileThr, obj, arg1, arg2);
rsync_t.detach();

现在,目标是定期检查这个分离的线程是否处于活动状态并正在运行。

我尝试了 future/promise 和异步的方式来做到这一点,但它需要 .get(),它类似于 join(),我不想要。

有什么建议吗?

提前致谢。

【问题讨论】:

不要分离,也不要等待 :) 使用正常的同步机制,如 mutex 和 condition_variable 进行信号传输。在程序退出之前加入线程。 是的,是的。那么有什么办法可以做到这一点吗?两个独立的线程并行运行,一个线程想知道另一个线程的状态。 @user1228352 我不明白是什么让你认为你需要detach 让线程并行运行。一旦你构造了std::thread,另一个线程就会开始运行。 唯一您没有并行性的情况是如果您调用join立即。但是你为什么要这样做呢? 【参考方案1】:

一旦你分离了一个线程,那么你就明确地说“我不需要等待这个线程完成”。这通常是因为线程从不结束,一直运行到程序结束。

在任何情况下,std::thread 都没有提供轮询机制来查看线程是否在没有等待的情况下完成。为此,您需要使用替代机制,无论线程是否分离。

一种选择是使用std::async(std::launch::async, func) 启动线程并使用返回的future 来检查线程是否仍在运行。

auto future=std::async(std::launch::async,thread_func);
bool thread_is_still_running=future.wait_for(std::chrono::seconds(0))!=std::future_status::ready;

如果您使用此选项,那么您将需要保留 future 对象(例如,通过将其存储在长期存在的 std::vector 或全局变量中),因为它的析构函数将等待线程完成。

或者,您可以使用std::mutex 和布尔标志,或在线程退出之前在线程内设置的std::atomic<bool> 来指示线程何时完成。

std::atomic<bool> done=false;

void thread_func()
  do_stuff();
  done=true;

【讨论】:

【参考方案2】:

使用std::async,您可以选择从未来检索任务状态。不必使用get()

https://en.cppreference.com/w/cpp/thread/future/wait_for

auto status = future.wait_for(std::chrono::milliseconds(1));
if (status == std::future_status::ready) 
    // Thread has finished

【讨论】:

【参考方案3】:

如果您将detachstd::thread 联系起来,您将失去std::thread 对象提供的通信渠道:

https://en.cppreference.com/w/cpp/thread/thread/detach

在调用 detach *this 后不再拥有任何线程。

如果你以后想以任何方式与分离的线程通信,你需要手动进行。在detach 之后,std::thread 不能再帮你了。

我正在使用分离线程,因为我不希望我的主线程等待/阻塞新的子线程,因为它还有许多其他重要的事情要做。

正确的解决方案可能不涉及detach。你不需要detach 让线程并行运行,当std::thread 构造函数返回时它已经并行运行。只需保持std::thread 对象处于活动状态并通过它进行查询,并且仅在线程实际上应该完成/结束时调用join。也就是说,std::thread 仅提供 joinable,它仅在 join 之后更改,因此它不提供您需要的信息(即您的代码以某种形式“完成”)。

【讨论】:

以上是关于如何在 C++11 中检查分离线程的状态?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查线程是不是处于休眠状态?

有没有一种可靠的方法可以强制线程在 C++ 中停止? (尤其是分离的)

android如何跨片段分离/附加保留视图状态

在 Kotlin Native 中,如何在不使用 C 指针的情况下将对象保留在单独的线程中,并从任何其他线程中改变其状态?

如何检查线程是不是正在等待?

如何检查c中信号量的状态?