本文简要介绍C++标准库提供的几种线程操作方法,主要介绍如何判断线程是否已经结束运行。
一、std::thread
std::thread 未直接提供判断线程是否结束的方法。
如果线程未进行 detach 且此时该线程处于 joinable 状态,析构该线程对象会触发异常。
线程处于 joinable 状态不代表线程正在执行,joinable 状态仅代表线程是可执行的,下面几种情况下线程会处于非 joinable 状态:
- 使用缺省构造函数构造的 std::thread 对象。
- 该线程对象的所有权已被 move 给其他对象。
- 该线程对象已经调用过 join 或 detach 函数。
由此可见,即便线程已经执行完成,只要未调用过 join 方法,线程仍然是 joinable 状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include <iostream> #include <thread>
std::thread Thread1() { std::thread t = std::thread([]() { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); }); return t; }
int main() { std::thread t1 = Thread1(); t1.join();
std::thread t2 = std::thread([]() { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
std::cout << "thread id:" << t2.get_id() << std::endl; std::cout << "joinable:" << t2.joinable() << std::endl; t2.detach(); std::cout << "joinable:" << t2.joinable() << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
return 0; }
|
还可以通过native_handle
方法获取线程的本地句柄,然后使用系统API函数来判断线程是否在运行,如:
1 2 3 4 5 6
| if(WaitForSingleObject((HANDLE)t.native_handle(), 0) == WAIT_OBJECT_0) { } else { }
|
二、std::async
通过std::async
可以判断线程是否结束运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include <iostream> #include <future>
int main() { std::future<void> f = std::async(std::launch::async, []() { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
bool isRunning = f.valid() && f.wait_for(std::chrono::milliseconds(0)) == std::future_status::timeout;
std::cout << isRunning << std::endl;
f.wait();
isRunning = f.valid() && f.wait_for(std::chrono::milliseconds(0)) == std::future_status::timeout;
std::cout << isRunning << std::endl;
return 0; }
|
2.1 判断 std::future 是否结束
1 2
| bool isRunning = f.valid() && f.wait_for(std::chrono::milliseconds(0)) == std::future_status::timeout;
|
2.2 std::shared_future
std::future
不支持赋值构造,需要使用std::shared_future
。
1 2 3 4 5
| std::shared_future<void> f1 = std::async(std::launch::async, []() { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
std::shared_future<void> f2 = f1;
|