C++11中引入了一個用於多線程操作的thread類,下面進行簡單演示如何使用,以及如果進行多線程同步。
thread簡單示例
#include <iostream> #include <thread> #include <Windows.h> using namespace std; void thread01() { for (int i = 0; i < 5; i++) { cout << "Thread 01 is working !" << endl; Sleep(100); } } void thread02() { for (int i = 0; i < 5; i++) { cout << "Thread 02 is working !" << endl; Sleep(200); } } int main() { thread task01(thread01); thread task02(thread02); task01.join(); task02.join(); for (int i = 0; i < 5; i++) { cout << "Main thread is working !" << endl; Sleep(200); } system("pause"); }
輸出:
thread detach不阻塞主線程
兩個子線程並行執行,join函數會阻塞主流程,所以子線程都執行完成之后才繼續執行主線程。可以使用detach將子線程從主流程中分離,獨立運行,不會阻塞主線程:
#include <iostream> #include <thread> #include <Windows.h> using namespace std; void thread01() { for (int i = 0; i < 5; i++) { cout << "Thread 01 is working !" << endl; Sleep(100); } } void thread02() { for (int i = 0; i < 5; i++) { cout << "Thread 02 is working !" << endl; Sleep(200); } } int main() { thread task01(thread01); thread task02(thread02); task01.detach(); task02.detach(); for (int i = 0; i < 5; i++) { cout << "Main thread is working !" << endl; Sleep(200); } system("pause"); }
輸出:
使用detach的主線程和兩個子線程並行執行。
thread帶參數子線程
在綁定的時候也可以同時給帶參數的線程傳入參數:
#include <iostream> #include <thread> #include <Windows.h> using namespace std; //定義帶參數子線程 void thread01(int num) { for (int i = 0; i < num; i++) { cout << "Thread 01 is working !" << endl; Sleep(100); } } void thread02(int num) { for (int i = 0; i < num; i++) { cout << "Thread 02 is working !" << endl; Sleep(200); } } int main() { thread task01(thread01, 5); //帶參數子線程 thread task02(thread02, 5); task01.detach(); task02.detach(); for (int i = 0; i < 5; i++) { cout << "Main thread is working !" << endl; Sleep(200); } system("pause"); }
輸出:
多線程同步mutex
多個線程同時對同一變量進行操作的時候,如果不對變量做一些保護處理,有可能導致處理結果異常:
#include <iostream> #include <thread> #include <Windows.h> using namespace std; int totalNum = 100; void thread01() { while (totalNum > 0) { cout << totalNum << endl; totalNum--; Sleep(100); } } void thread02() { while (totalNum > 0) { cout << totalNum << endl; totalNum--; Sleep(100); } } int main() { thread task01(thread01); thread task02(thread02); task01.detach(); task02.detach(); system("pause"); }
部分輸出結果:
有兩個問題,一是有很多變量被重復輸出了,而有的變量沒有被輸出;二是正常情況下每個線程輸出的數據后應該緊跟一個換行符,但這里大部分卻是另一個線程的輸出。
這是由於第一個線程對變量操作的過程中,第二個線程也對同一個變量進行各操作,導致第一個線程處理完后的輸出有可能是線程二操作的結果。針對這種數據競爭的情況,可以使用線程互斥對象mutex保持數據同步。mutex類的使用需要包含頭文件mutex。
#include <iostream> #include <thread> #include <Windows.h> #include <mutex> using namespace std; mutex mu; //線程互斥對象 int totalNum = 100; void thread01() { while (totalNum > 0) { mu.lock(); //同步數據鎖 cout << totalNum << endl; totalNum--; Sleep(100); mu.unlock(); //解除鎖定 } } void thread02() { while (totalNum > 0) { mu.lock(); cout << totalNum << endl; totalNum--; Sleep(100); mu.unlock(); } } int main() { thread task01(thread01); thread task02(thread02); task01.detach(); task02.detach(); system("pause"); }
多線程中加入mutex互斥對象之后輸出正常: