C++使用thread類進行多執行緒程式設計
阿新 • • 發佈:2018-11-29
C++11中引入了一個用於多執行緒操作的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"); }
輸出:
兩個子執行緒並行執行,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的主執行緒和兩個子執行緒並行執行。
帶參子執行緒
在繫結的時候也可以同時給帶引數的執行緒傳入引數:
#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"); }
輸出跟上例輸出一樣:
多執行緒資料競爭
多個執行緒同時對同一變數進行操作的時候,如果不對變數做一些保護處理,有可能導致處理結果異常:
#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互斥物件之後輸出正常:
後記:
C++11之前,Windows系統為我們提供了相關API,我們可以使用他們來進行多執行緒程式設計。