在C++中,std::thread
类提供了对线程的操作和管理。理解join()
方法和joinable()
方法之间的区别对于正确使用多线程至关重要。
join()
join()
是std::thread
类的一个成员函数,它的作用是等待线程完成执行。如果一个线程对象是可连接的(即它代表了一个执行中的线程),调用它的join()
方法会阻塞当前线程(即调用join()
的线程),直到与之关联的线程完成执行。这意味着join()
用于确保一个线程完成其执行任务,从而避免任何潜在的并发问题。- 一旦
join()
被调用并完成,线程对象就不再是可连接的,也就是说,它不再代表一个执行中的线程。这意味着对同一个线程对象再次调用join()
会导致程序错误(具体来说,是std::system_error
异常)。 - 使用
join()
是一种同步机制,确保所有线程按照程序员的意图顺序执行和完成。
joinable()
joinable()
也是std::thread
类的一个成员函数,它用于检查线程对象是否代表了一个执行中的线程。如果线程对象是可连接的,即它代表了一个尚未结束的线程,joinable()
返回true
;否则,返回false
。joinable()
非常有用,因为它允许程序在尝试join()
一个线程之前检查它是否可连接。这是一种安全措施,可以避免因重复join()
同一个线程或尝试join()
一个未启动的线程而导致的错误。
区别
总结一下join()
和joinable()
之间的主要区别:
- 作用:
join()
用于等待线程完成执行;joinable()
用于检查线程是否可连接。 - 返回类型:
join()
没有返回值;joinable()
返回一个布尔值,指示线程是否可连接。 - 使用场景:
join()
用于当你需要确保线程完成其任务时。joinable()
用于在尝试join()
、detach()
或执行其他需要知道线程状态的操作之前,检查线程的状态。
示例
#include <iostream>
#include <thread>
void task() {
// 模拟耗时任务
std::this_thread::sleep_for(std::chrono::seconds(1));
}
int main() {
std::thread t(task);
if (t.joinable()) {
std::cout << "Thread is joinable before join()." << std::endl;
t.join();
}
if (!t.joinable()) {
std::cout << "Thread is not joinable after join()." << std::endl;
}
return 0;
}
在这个示例中,我们首先检查线程t
在调用join()
之前是否可连接,然后再次检查它在调用join()
之后的状态。这演示了如何使用joinable()
来避免在一个已经不再代表执行中的线程上调用join()
的错误。