kis*_*ljr 76 c++ multithreading c++11 stdthread
如何检查a std::thread是否仍在运行(以独立于平台的方式)?它缺乏一种timed_join()方法,joinable()并不适用于此.
我想std::lock_guard在线程中使用a锁定互斥锁并使用try_lock()互斥锁的方法来确定它是否仍然被锁定(线程正在运行),但对我来说似乎不必要的复杂.
你知道更优雅的方法吗?
更新:要明确:我想检查线程是否干净地退出.为此,"悬挂"线程被认为正在运行.
Snp*_*nps 103
如果您愿意使用C++ 11 std::async并std::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.
}
Run Code Online (Sandbox Code Playgroud)
如果必须使用,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.
}
Run Code Online (Sandbox Code Playgroud)
这两个例子都将输出:
Thread still running
Run Code Online (Sandbox Code Playgroud)
这当然是因为在任务完成之前检查了线程状态.
但话说回来,就像其他人已经提到的那样做起来可能更简单:
#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.
}
Run Code Online (Sandbox Code Playgroud)
编辑:
除了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.
}
Run Code Online (Sandbox Code Playgroud)
您可以使用这种简单的机制来检测线程的完成情况,而不会在 join 方法中阻塞。
std::thread thread([&thread]() {
sleep(3);
thread.detach();
});
while(thread.joinable())
sleep(1);
Run Code Online (Sandbox Code Playgroud)
一个简单的解决方案是有一个布尔变量,线程在定期的时间间隔内设置为true,并且由想要知道状态的线程检查并设置为false.如果变量为false,则该线程不再被视为活动状态.
一种更安全的方法是让一个由子线程增加的计数器,并且主线程将计数器与存储的值进行比较,如果在很长时间后相同,那么子线程被认为是不活动的.
但请注意,C++ 11中没有办法实际杀死或删除已挂起的线程.
编辑如何检查线程是否已完全退出:基本上与第一段中描述的技术相同; 将布尔变量初始化为false.子线程执行的最后一件事是将其设置为true.然后主线程可以检查该变量,如果为true则在子线程上进行连接而没有太多(如果有的话)阻塞.
Edit2如果线程由于异常而退出,则有两个线程"main"函数:第一个函数有一个try- catch在其中调用第二个"真正的"主线程函数.第一个main函数设置"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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
84960 次 |
| 最近记录: |