首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何检查std::thread是否仍在运行?

如何检查std::thread是否仍在运行?
EN

Stack Overflow用户
提问于 2012-02-01 18:41:20
回答 7查看 124.5K关注 0票数 96

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

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

你知道更优雅的方法吗?

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

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2013-06-20 10:11:59

如果您愿意使用C++11 std::asyncstd::future来运行您的任务,那么您可以使用std::futurewait_for函数来检查线程是否仍在以如下方式运行:

代码语言:javascript
复制
#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来获取未来的对象:

代码语言:javascript
复制
#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.
}

这两个示例都将输出:

代码语言:javascript
复制
Thread still running

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

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

代码语言:javascript
复制
#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::thread配合使用的std::packaged_task,它比使用std::promise更简洁

代码语言:javascript
复制
#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.
}
票数 133
EN

Stack Overflow用户

发布于 2012-02-01 18:47:52

一种简单的解决方案是有一个布尔变量,线程每隔一段时间就将该变量设置为true,希望知道状态的线程会检查该变量并将其设置为false。如果变量to long为false,则该线程不再被视为活动线程。

一种更安全的线程方法是拥有一个由子线程增加的计数器,主线程将该计数器与存储的值进行比较,如果在太长时间后相同,则认为该子线程不活动。

但是请注意,在C++11中没有办法实际杀死或删除挂起的线程。

编辑如何检查线程是否干净地退出:基本上与第一段中描述的技术相同;将一个布尔变量初始化为false。子线程做的最后一件事是将其设置为true。然后,主线程可以检查该变量,如果为真,则在子线程上执行联接,而不会阻塞太多(如果有的话)。

Edit2如果线程由于异常而退出,则有两个线程" main“函数:第一个函数有一个try-catch,它在其中调用第二个”真正的“主线程函数。第一个主函数设置"have_exited“变量。如下所示:

代码语言:javascript
复制
bool thread_done = false;

void *thread_function(void *arg)
{
    void *res = nullptr;

    try
    {
        res = real_thread_function(arg);
    }
    catch (...)
    {
    }

    thread_done = true;

    return res;
}
票数 5
EN

Stack Overflow用户

发布于 2016-03-26 01:11:30

这个简单的机制可以用来检测线程的完成情况,而不会在join方法中阻塞。

代码语言:javascript
复制
std::thread thread([&thread]() {
    sleep(3);
    thread.detach();
});

while(thread.joinable())
    sleep(1);
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9094422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档