如何检查std::thread
是否仍在运行(以独立于平台的方式)?它缺少timed_join()
方法,而joinable()
不是为此而设计的。
我想过用线程中的std::lock_guard
锁定一个互斥锁,并使用互斥锁的try_lock()
方法来确定它是否仍然被锁定(线程正在运行),但对我来说,这似乎是不必要的复杂。
你知道更优雅的方法吗?
更新:声明:我想检查线程是否干净地退出了。出于此目的,“挂起”线程被视为正在运行。
发布于 2013-06-20 10:11:59
如果您愿意使用C++11 std::async
和std::future
来运行您的任务,那么您可以使用std::future
的wait_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::thread
配合使用的std::packaged_task
,它比使用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.
}
发布于 2012-02-01 18:47:52
一种简单的解决方案是有一个布尔变量,线程每隔一段时间就将该变量设置为true,希望知道状态的线程会检查该变量并将其设置为false。如果变量to long为false,则该线程不再被视为活动线程。
一种更安全的线程方法是拥有一个由子线程增加的计数器,主线程将该计数器与存储的值进行比较,如果在太长时间后相同,则认为该子线程不活动。
但是请注意,在C++11中没有办法实际杀死或删除挂起的线程。
编辑如何检查线程是否干净地退出:基本上与第一段中描述的技术相同;将一个布尔变量初始化为false。子线程做的最后一件事是将其设置为true。然后,主线程可以检查该变量,如果为真,则在子线程上执行联接,而不会阻塞太多(如果有的话)。
Edit2如果线程由于异常而退出,则有两个线程" main“函数:第一个函数有一个try
-catch
,它在其中调用第二个”真正的“主线程函数。第一个主函数设置"have_exited“变量。如下所示:
bool thread_done = false;
void *thread_function(void *arg)
{
void *res = nullptr;
try
{
res = real_thread_function(arg);
}
catch (...)
{
}
thread_done = true;
return res;
}
发布于 2016-03-26 01:11:30
这个简单的机制可以用来检测线程的完成情况,而不会在join方法中阻塞。
std::thread thread([&thread]() {
sleep(3);
thread.detach();
});
while(thread.joinable())
sleep(1);
https://stackoverflow.com/questions/9094422
复制相似问题