上一次講述了多線程編程,但是由於線程是共享內存空間和資源的,這就導致:在使用多線程的時候,對於共享資源的控制要做的很好。先上程序:
1 #include <iostream> 2 #include <thread> 3 #include <chrono> 4 #include <mutex> 5 6 using namespace std; 7 8 mutex mtx; 9 10 void fn1() 11 { 12 for (int i = 0; i < 5; i++) 13 { 14 mtx.lock(); 15 cout << "線程" << this_thread::get_id() << ":" << "The thread1 is running !" << endl; 16 mtx.unlock(); 17 } 18 } 19 20 void fn2() 21 { 22 for (int i = 0; i < 5; i++) 23 { 24 mtx.lock();//鎖住的是什么資源,什么時候加鎖? 25 cout << "線程" << this_thread::get_id() << ":" << "The thread2 is running !" << endl; 26 mtx.unlock(); 27 } 28 } 29 30 int main() 31 { 32 thread t1(fn1); 33 thread t2(fn2); 34 t1.detach();//this_thread是否表示當前進行,而這里的當前進程是否是main函數所在進程 35 t2.detach(); 36 this_thread::sleep_for(chrono::milliseconds(1000));//sleep_for表示當前進行休眠一段時間,不與其他進程競爭CPU 37 cout << "主線程端口:" << this_thread::get_id() << endl; 38 getchar(); 39 return 0; 40 }
上面一段程序,在main進程中創建了兩個子線程t1,t2。對各個子線程的cout輸出流進行了加鎖,完了又對鎖進行了釋放。
其結果如下:
可見:線程t1,t2是交替執行的(這是由CPU時間片輪換造成的?)。假如我們不對cout輸出流加鎖,我們看看代碼:
1 #include <iostream> 2 #include <thread> 3 #include <chrono> 4 #include <mutex> 5 6 using namespace std; 7 8 mutex mtx; 9 10 void fn1() 11 { 12 for (int i = 0; i < 5; i++) 13 { 14 //mtx.lock(); 15 cout << "線程" << this_thread::get_id() << ":" << "The thread1 is running !" << endl; 16 //mtx.unlock(); 17 } 18 } 19 20 void fn2() 21 { 22 for (int i = 0; i < 5; i++) 23 { 24 //mtx.lock();//鎖住的是什么資源,什么時候加鎖? 25 cout << "線程" << this_thread::get_id() << ":" << "The thread2 is running !" << endl; 26 //mtx.unlock(); 27 } 28 } 29 30 int main() 31 { 32 thread t1(fn1); 33 thread t2(fn2); 34 t1.detach();//this_thread是否表示當前進行,而這里的當前進程是否是main函數所在進程 35 t2.detach(); 36 this_thread::sleep_for(chrono::milliseconds(1000));//sleep_for表示當前進行休眠一段時間,不與其他進程競爭CPU 37 cout << "主線程端口:" << this_thread::get_id() << endl; 38 getchar(); 39 return 0; 40 }
(就是單純的注釋掉了加鎖)。
結果如下:
可以看到,結果產生了紊亂,分析一下這個結果:
線程t1才執行了一點:剛輸出完“線程”兩個字,轉到線程2執行了,接下來再輸出了線程t1的內容(並不是跑回去執行線程t1),再去執行線程t1.
造成這種紊亂的原因是:
cout本質上是一個輸出流對象,相當於一個公共接口,這個接口是一個公共資源。這里就涉及到了資源共享的問題!!!
所以要對cout這個共享資源加鎖!!!這樣等當前的輸出流執行完,才會到下一個線程!!