c++ - 如何检查 std::thread 是否仍在运行?

标签 c++ multithreading c++11 stdthread

如何检查 std::thread 是否仍在运行(以独立于平台的方式)? 它缺少一个 timed_join() 方法,而 joinable() 并不适用于此。

我想过在线程中用 std::lock_guard 锁定一个互斥体,并使用互斥体的 try_lock() 方法来确定它是否仍然被锁定(线程正在运行),但对我来说似乎不必要地复杂。

你知道更优雅的方法吗?

更新:要明确:我想检查线程是否干净地退出。出于此目的,“挂起”线程被视为正在运行。

最佳答案

如果你愿意使用 C++11 std::asyncstd::future运行您的任务,那么您可以使用 wait_for std::future的功能检查线程是否仍然以这样的简洁方式运行:

#include <future>
#include <thread>
#include <chrono>
#include <iostream>

int main() {
    using namespace std::chrono_literals;

    /* Run some task on new thread. The launch policy std::launch::async
       makes sure that the task is run asynchronously on a new thread. */
    auto future = std::async(std::launch::async, [] {
        std::this_thread::sleep_for(3s);
        return 8;
    });

    // Use wait_for() with zero milliseconds to check thread status.
    auto status = future.wait_for(0ms);

    // Print status.
    if (status == std::future_status::ready) {
        std::cout << "Thread finished" << std::endl;
    } else {
        std::cout << "Thread still running" << std::endl;
    }

    auto result = future.get(); // Get result.
}

如果您必须使用 std::thread那么你可以使用std::promise获取 future 对象:

#include <future>
#include <thread>
#include <chrono>
#include <iostream>

int main() {
    using namespace std::chrono_literals;

    // Create a promise and get its future.
    std::promise<bool> p;
    auto future = p.get_future();

    // Run some task on a new thread.
    std::thread t([&p] {
        std::this_thread::sleep_for(3s);
        p.set_value(true); // Is done atomically.
    });

    // Get thread status using wait_for as before.
    auto status = future.wait_for(0ms);

    // Print status.
    if (status == std::future_status::ready) {
        std::cout << "Thread finished" << std::endl;
    } else {
        std::cout << "Thread still running" << std::endl;
    }

    t.join(); // Join thread.
}

这两个例子都会输出:

Thread still running

这当然是因为在任务完成之前检查线程状态。

但话又说回来,像其他人已经提到的那样做可能会更简单:

#include <thread>
#include <atomic>
#include <chrono>
#include <iostream>

int main() {
    using namespace std::chrono_literals;

    std::atomic<bool> done(false); // Use an atomic flag.

    /* Run some task on a new thread.
       Make sure to set the done flag to true when finished. */
    std::thread t([&done] {
        std::this_thread::sleep_for(3s);
        done = true;
    });

    // Print status.
    if (done) {
        std::cout << "Thread finished" << std::endl;
    } else {
        std::cout << "Thread still running" << std::endl;
    }

    t.join(); // Join thread.
}

编辑:

还有std::packaged_task用于 std::thread比使用 std::promise 更清洁的解决方案:

#include <future>
#include <thread>
#include <chrono>
#include <iostream>

int main() {
    using namespace std::chrono_literals;

    // Create a packaged_task using some task and get its future.
    std::packaged_task<void()> task([] {
        std::this_thread::sleep_for(3s);
    });
    auto future = task.get_future();

    // Run task on new thread.
    std::thread t(std::move(task));

    // Get thread status using wait_for as before.
    auto status = future.wait_for(0ms);

    // Print status.
    if (status == std::future_status::ready) {
        // ...
    }

    t.join(); // Join thread.
}

关于c++ - 如何检查 std::thread 是否仍在运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9094422/

相关文章:

c++ - 对构造函数的调用不能出现在常量表达式中

java - JNI应用程序挂起

java - 线程之间共享hashmap

c++ - std::thread、类构造函数和析构函数

c++ - std::enable_if 有条件地编译一个成员函数

c++ - Xcode 和 wxWidgets 框架

c++ - 为什么异常处理在 C++ 中经常被看不起?

c - 在 C 中使用 PThreads 合并排序

c++ - 清理拥有的 (!) 字符串成员时析构函数偶尔崩溃

c++ - Boost.test找不到main