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");
}
輸出:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CN4IzM5ETN3ADNiVDOkJjMzYzX1MjN0UTM1EzLclDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
兩個子線程并行執行,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");
}