如何检查一个std ::线程是否仍在运行?

我怎样才能检查一个std::thread是否仍在运行(平台独立的方式)? 它缺lesstimed_join()方法,而timed_join()并不意味着这一点。

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

你知道更优雅的方法吗?

更新:要清楚:我想检查线程干净退出或不。 为此,“悬挂”线程被认为正在运行。

如果你愿意使用C ++ 11 std::asyncstd::future来运行你的任务,那么你可以利用std::futurewait_for函数来检查线程是否还在运行喜欢这个:

 #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来获得未来的对象:

 #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::threadstd::promise更清洁的解决scheme:

 #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. } 

一个简单的解决scheme是有一个布尔variables,线程将定期设置为true,并通过想知道状态的线程检查并设置为false。 如果variables为false,则线程不再被视为活动线程。

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

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

编辑如何检查线程是否已经完全退出:基本上与第一段中描述的技术相同; 有一个布尔variables初始化为false。 子线程所做的最后一件事是将其设置为true。 然后,主线程可以检查该variables,如果为true,则在没有太多(如果有的话)阻塞的情况下在子线程上执行联接。

Edit2如果线程由于exception而退出,那么就有两个线程“main”函数:第一个函数有一个trycatch函数,在其中调用第二个“real”主线程函数。 这第一个主函数设置“has_exited”variables。 像这样的东西:

 bool thread_done = false; void *thread_function(void *arg) { void *res = nullptr; try { res = real_thread_function(arg); } catch (...) { } thread_done = true; return res; } 

创build正在运行的线程和调用线程都可以访问的互斥锁。 当正在运行的线程启动时,它会locking互斥锁,当它结束时它会解锁互斥锁。 为了检查线程是否仍在运行,调用线程调用mutex.try_lock()。 返回值是线程的状态。 (只要确保解锁互斥体,如果try_lock工作)

与此有关的一个小问题,mutex.try_lock()将在创build线程和locking互斥锁之间返回false,但是可以使用稍微复杂的方法避免这种情况。

当然有一个互斥包装的variables被初始化为false ,线程设置为true是退出前的最后一件事情。 这足够primefaces满足您的需求吗?

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

 std::thread thread([&thread]() { sleep(3); thread.detach(); }); while(thread.joinable()) sleep(1);