#include<iostream>#include<thread>#include<chrono>usingnamespace std;int gu_num=0;voidprint(int id){for(int i=0;i<5;i++){++gu_num;
cout <<"id = "<< id <<" ==> "<< gu_num << endl;
std::this_thread::sleep_for(std::chrono::seconds(1));}}intmain(){
thread t1(print,0);
thread t2(print,1);
t1.join();
t2.join();return0;}
Output:
g++-o mutex mutex.cpp -lpthread
./mutex
id = id =01==>==>22
id = id =1==>40==>4
id =1==>5
id =0==>6
id =1==>8
id =0==>8
id =1==>9
id =0==>10
Atomic
#include<iostream>#include<thread>#include<chrono>#include<atomic>usingnamespace std;
atomic_int gu_num(0);voidprint(int id){for(int i=0;i<5;i++){++gu_num;
cout <<"id = "<< id <<" ==> "<< gu_num << endl;
std::this_thread::sleep_for(std::chrono::seconds(1));}}intmain(){
thread t1(print,0);
thread t2(print,1);
t1.join();
t2.join();return0;}
Output:./mutex
id =0==>2id =1==>2
id =1==>3
id =0==>4
id =1==>5
id =0==>6
id =0==>8
id =1==>8
id =0==>9
id =1==>10
Mutex
Mutex: Protect global variable only lock
#include<iostream>#include<thread>#include<chrono>#include<atomic>#include<mutex>usingnamespace std;int gu_num=0;//atomic_int gu_num (0);
std::mutex mtx;voidprint(int id){for(int i=0;i<5;i++){
mtx.lock();++gu_num;
cout <<"id = "<< id <<" ==> "<< gu_num << endl;//mtx.unlock(); For ti, id=0, it has been blocked here
std::this_thread::sleep_for(std::chrono::seconds(1));}}intmain(){
thread t1(print,0);
thread t2(print,1);
t1.join();
t2.join();return0;}
Output:./mutex
id =0==>1//In the process of blocking
Mutex: Protect global variable with lock and unblock
#include<iostream>#include<thread>#include<chrono>#include<atomic>#include<mutex>usingnamespace std;int gu_num=0;//atomic_int gu_num (0);
std::mutex mtx;voidprint(int id){for(int i=0;i<5;i++){
mtx.lock();++gu_num;
cout <<"id = "<< id <<" ==> "<< gu_num << endl;
mtx.unlock();
std::this_thread::sleep_for(std::chrono::seconds(1));}}intmain(){
thread t1(print,0);
thread t2(print,1);
t1.join();
t2.join();return0;}
Output:./mutex
id =0==>1
id =1==>2
id =0==>3
id =1==>4
id =0==>5
id =1==>6
id =1==>7
id =0==>8
id =1==>9
id =0==>10
Rright example
#include<iostream>#include<thread>#include<chrono>#include<atomic>#include<mutex>usingnamespace std;int gu_num=0;
std::mutex mtx;voidprint(int id){for(int i=0;i<5;i++){while(!mtx.try_lock()){
cout <<" failed "<< endl;}++gu_num;
cout <<"Success: id = "<< id <<" ==> "<< gu_num << endl;
mtx.unlock();
std::this_thread::sleep_for(std::chrono::microseconds(200));}}intmain(){
thread t1(print,0);
thread t2(print,1);
t1.join();
t2.join();return0;}
Output:./mutex
Success: id =0==>1
failed
Success: id =1==>2
Success: id =0==>3
Success: id =1==>4
Success: id =0==>5
Success: id =1==>6
Success: id =0==>7
Success: id =1==>8
Success: id =0==>9
Success: id =1==>10
Conditional variable
Notify the blocked thread that the global variable value changed notify_all,notify_all
Block a thread to be waited until this thread was notified wait,wait_for
Print 1-100 with multi-thread
#include<iostream>#include<time.h>#include<thread>#include<chrono>#include<atomic>#include<mutex>usingnamespace std;int n=100;int i =1;//std::mutex mtx;voidprint(){for(i=1;i<=n;i++){
cout <<"Line"<< i <<": "<< i <<endl;}}intmain(){
clock_t start,end;
start =clock();
thread t(print);
t.join();
end =clock();
cout <<"Run : "<<(end - start)<< endl;
cout <<"i= "<<(i-1)<<endl;return0;}
Output:
Line1:1
Line2:2
Line3:3
Line4:4........
Line97:97
Line98:98
Line99:99
Line100:100
Run :165
i=100
Print 100 times “ABCABC” with three-thread
#include<iostream>#include<time.h>#include<thread>#include<chrono>#include<atomic>#include<mutex>#include<condition_variable>usingnamespace std;
std::mutex mtx;
std::condition_variable cv;int i=0;int isReady =0;constint n =100;voidprintA(){
std::unique_lock<std::mutex>lck(mtx);//unique_lock can auto unlockwhile(i<=n){while(isReady !=0){
cv.wait(lck);//isReady = 0 ia a signal to notify printA, so if isReady!0,A should be waiting }
isReady=1;if(i>=n){
cv.notify_all();break;}++i;
cout <<"threadA : "<< i << endl ;
cv.notify_all();}
cout <<"threadA Finish!"<< endl;}voidprintB(){
std::unique_lock<std::mutex>lck(mtx);while(i<=n){while(isReady !=1){
cv.wait(lck);}
isReady=2;if(i>=n){
cv.notify_all();break;}++i;
cout <<"threadB : "<< i << endl ;
cv.notify_all();}
cout <<"threadB Finish!"<< endl;}voidprintC(){
std::unique_lock<std::mutex>lck(mtx);while(i<=n){while(isReady !=2){
cv.wait(lck);}
isReady=0;if(i>=n){
cv.notify_all();break;}++i;
cout <<"threadC : "<< i << endl ;
cv.notify_all();}
cout <<"threadC Finish!"<< endl;}intmain(){
clock_t start,end;
start =clock();
thread A(printA);
thread B(printB);
thread C(printC);
A.join();
B.join();
C.join();
end =clock();
cout << endl <<"i= "<< i << endl;
cout <<"Run : "<<(end - start)<< endl;return0;}
Output:
threadA :1
threadB :2
threadC :3
threadA :4.......
threadA :97
threadB :98
threadC :99
threadA :100
threadB Finish!
threadC Finish!
threadA Finish!
i=100
Run :931
+-----------------------------------------+
| Three-thread print "ABC"until100|
+-----------------------------------------+
|
V
/-----------\ N
| i<100|-------------+
\-----------/ || Y |
V |
+-------------+ || printA ||
+-------------+ |||
V |
N /-----------------------\|
+---| Get printC notify |<--+ ||\-----------------------/ |||| Y ||| V ||| +---------------+ |||| print "A"|||| +---------------+ ||||||| V ||| +---------------+ ||||isReady=1|||| +---------------+ ||||||| V ||| +---------+ |||| ++i |||| +---------+ ||||||| V ||| +-------------------+ |||| notify printB |-----+ || +-------------------+ |||||| +-----------+ |
+-------->|wait||
+-----------+ |||
V |
+-------------+ || printB ||
+-------------+ |||
V |
N /-----------------------\|
+---| Get printA notify |<--+ ||\-----------------------/ |||| Y ||| V ||| +---------------+ |||| print "B"|||| +---------------+ ||||||| V ||| +---------------+ ||||isReady=2|||| +---------------+ ||||||| V ||| +---------+ |||| ++i |||| +---------+ ||||||| V ||| +-------------------+ |||| notify printC |-----+ || +-------------------+ |||||| +-----------+ |
+-------->|wait||
+-----------+ |||
V |
+-------------+ || printC ||
+-------------+ |||
V |
N /-----------------------\|
+---| Get printB notify |<--+ ||\-----------------------/ |||| Y ||| V ||| +---------------+ |||| print "C"|||| +---------------+ ||||||| V ||| +---------------+ ||||isReady=0|||| +---------------+ ||||||| V ||| +---------+ |||| ++i |||| +---------+ ||||||| V ||| +-------------------+ |||| notify printA |-----+ || +-------------------+ |||||| +-----------+ |
+-------->|wait||
+-----------+ |||
V |
O<------------------+
#include<iostream>#include<time.h>#include<thread>#include<chrono>#include<atomic>#include<mutex>#include<condition_variable>usingnamespace std;
std::mutex mtx;
std::condition_variable cv;int i=1;int isReady =0;constint n =100;voidprintA(){
std::this_thread::sleep_for(std::chrono::seconds(2));
std::unique_lock<std::mutex>lck(mtx);//unique_lock can auto unlockwhile(i<n){while(isReady !=0){
cv.wait(lck);//isReady = 0 ia a signal to notify printA, so if isReady!0,A should be waiting }
cout <<"A ";
isReady=1;if(i>=n){
cv.notify_all();break;}++i;
cv.notify_all();}}voidprintB(){
std::this_thread::sleep_for(std::chrono::seconds(2));
std::unique_lock<std::mutex>lck(mtx);while(i<n){while(isReady !=1){
cv.wait(lck);}
cout<<"B ";
isReady=2;if(i>=n){
cv.notify_all();break;}++i;
cv.notify_all();}}voidprintC(){
std::this_thread::sleep_for(std::chrono::seconds(2));
std::unique_lock<std::mutex>lck(mtx);while(i<n){while(isReady !=2){
cv.wait(lck);}
cout<<"C ";
isReady=0;if(i>=n){
cv.notify_all();break;}++i;
cv.notify_all();}}intmain(){
thread A(printA);
thread B(printB);
thread C(printC);
A.join();
B.join();
C.join();
cout << endl <<"i= "<< i << endl;return0;}
Output:
A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C A B
i=100