一、thread join簡介
thread join是線程同步的一種機制,它能夠在一個線程中等待另一個線程執行完畢之後再繼續執行。
線程是計算機操作系統中最小的執行單位,如果一個進程需要同時處理多個任務,那麼可以創建多個線程來同時處理任務,這減少了進程切換和創建線程的開銷,提高了執行效率。
在這種多線程的情況下,為了保證任務完成的正確性,我們要考慮線程之間的同步問題,這就是thread join可以解決的問題。
二、使用thread join實現線程同步
一般情況下,主線程會創建多個子線程,這些子線程會在執行自己的任務的同時,還需要等待其他子線程執行完畢之後才能繼續執行。這個時候就需要使用thread join來實現。
下面示例代碼創建了三個線程,它們每個都會打印1到5,但是要求線程1必須先打印1到5,然後線程2打印1到5,最後線程3打印1到5。
#include <thread>
#include <iostream>
#include <mutex>
// 每個線程都要輸出1到5,但必須保證線程1先輸出,線程2其次,線程3最後
std::mutex mtx;
void printNum(int num, int threadNum) {
for (int i = 1; i <= 5; i++) {
// 保證每個線程輸出時不會被阻塞
std::unique_lock<std::mutex> lck(mtx);
if (threadNum == 1) {
std::cout << "Thread1:" << num++ << std::endl;
} else if (threadNum == 2) {
std::cout << "Thread2:" << num++ << std::endl;
} else if (threadNum == 3) {
std::cout << "Thread3:" << num++ << std::endl;
}
}
}
int main() {
int num = 1;
// 創建三個線程,並讓它們輸出
std::thread t1(printNum, num, 1);
std::thread t2(printNum, num, 2);
std::thread t3(printNum, num, 3);
// 等待三個線程都執行完畢
t1.join();
t2.join();
t3.join();
return 0;
}
在這個示例代碼中,我們使用了mutex來保證多線程的安全性,同時使用了unique_lock來保證每個線程輸出時不會被阻塞。最後在主線程中使用了join函數,來保證每個子線程都執行完畢之後,主線程再繼續執行。
三、thread join的使用注意事項
1、注意線程的生命周期
在使用thread join的時候,一定要注意線程的生命周期,如果一個線程被join之後,就不能再次使用該線程對象進行join,否則會拋出系統異常。
#include <thread>
#include <iostream>
void hello() {
std::cout << "Hello World!" << std::endl;
}
int main() {
std::thread t(hello);
// 等待線程t執行完畢
t.join();
// 再次等待線程t執行完畢,會拋出異常
t.join();
return 0;
}
2、join的執行順序
如果有多個線程需要執行join操作,那麼它們的執行順序也是需要注意的。一般情況下,應該按照子線程的創建順序依次執行join,這樣才能保證主線程能夠等待所有子線程都執行完畢之後再繼續執行。
#include <thread>
#include <iostream>
void printNum(int num) {
std::cout << num << std::endl;
}
int main() {
std::thread t1(printNum, 1);
std::thread t2(printNum, 2);
std::thread t3(printNum, 3);
// 等待t2線程執行完畢
t2.join();
// 等待t3線程執行完畢
t3.join();
// 等待t1線程執行完畢
t1.join();
return 0;
}
3、對於同一個線程只能調用一次join
如果對於同一個線程多次調用join函數,那麼只有第一次會生效,其他的調用會被忽略。
#include <thread>
#include <iostream>
void hello(int num) {
std::cout << "Hello World " << num << std::endl;
}
int main() {
std::thread t(hello, 1);
// 等待t線程執行完畢
t.join();
// 再次等待t線程執行完畢,會被忽略
t.join();
return 0;
}
四、總結
Thread join是線程同步的一種機制,它能夠在一個線程中等待另一個線程執行完畢之後再繼續執行。在使用thread join的時候,一定要注意線程的生命周期,以及join的執行順序和對於同一個線程只能調用一次join。
使用thread join能夠解決多線程競爭的問題,提高程序的可靠性和可維護性。在實際的開發過程中,我們需要根據具體的場景來決定是否需要使用thread join,以及如何使用thread join。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/198593.html
微信掃一掃
支付寶掃一掃