C++11多線程編程(常見面試題)

【題目1】ios

子線程循環 10 次,接着主線程循環 100 次,接着又回到子線程循環 10 次,接着再回到主線程又循環 100 次,如此循環50次,試寫出代碼ide

 

【題解】spa

首先咱們來分析一下這道題...(是個剛入門的小白,分析的很差請見諒)線程

一、因爲子線程須要循環10次不受主線程干擾,而主線程須要循環100次不受子線程干擾,因此顯然,在他們進入循環的時候須要一個鎖把這段循環鎖住,否則會致使資源被搶佔(此處的資源能夠理解爲是循環裏的cout)。(其實簡單來講互斥量是爲了保證子線程和主線程的for不一樣時進行code

二、而後問題來了,怎麼控制子線程循環後主線程循環,而後一直這樣依次循環呢?條件變量就能夠作到這點,咱們能夠經過改變某個全局變量的值,第一次將該全局變量置爲10,也就是說咱們只要控制若是傳入的參數和該全局變量不等,就讓他一直等待,當執行完子線程的循環後改變這個全局變量爲100,那麼對於子線程來講全局變量和傳入的參數就不相等了,那麼條件變量就會一直等待。固然若是一直讓他等待確定是不對的,因此當一個線程執行完循環以後須要喚醒這個條件變量,告訴線程變量已經改變又能夠開始搶資源啦。(其實條件變量就是爲了控制子主線程運行的前後條件blog

 

【代碼】資源

#include<thread> #include<iostream> #include<cstdio> #include<mutex> #include<condition_variable>
using namespace std; int flag = 10; mutex mu; condition_variable cv; void fun(int x, char c) { for (int i = 0; i < 50; i++) { unique_lock<mutex> lock(mu); while(flag != x) cv.wait(lock);//在該線程阻塞以前會執行lock.unlock,這樣別的線程纔不會被鎖住
        for (int j = 0; j < x; j++) cout << c << ":" << j << endl; flag = (x == 10)? 100 : 10; cv.notify_one(); } } int main() { thread t1(fun, 10, 'A'); fun(100, 'B'); t1.join(); }
View Code

 

【總結】it

理解這段代碼的時候,被wait()弄了很久,多是我太蠢qwq那麼來講一下wait()吧,咱們分兩種狀況來講。io

(1)一開始,主線程先搶到了鎖入門

那麼就會判斷flag是否等於x,很顯然若是是主線程先拿到鎖此時flag=10,x=100不等,那麼這個時候主線程就會執行wait(),也就是會被阻塞,而後由於wait()自身有這樣一個機制(當他執行的時候會自動釋放鎖嗎,也就是會自動執行unlock,給其餘線程一個拿鎖的機會),這個時候子線程就會拿到鎖,而且判斷fag是否等於x,這時候明顯是相等的,那麼就會進行下面的一系列循環,這個時候重點來了,必定要改變全局變量!!若是不改變會是什麼結果呢?假設咱們把那句話註釋掉直接執行notify_one(),那麼主線程就會被喚醒它的wait()又會自動參與搶鎖,因爲flag沒有改變,那麼flag和x的值仍是相等,因此它依然會被阻塞,那麼依舊就是子線程執行,就不知足題意了。

(2)一開始,子線程先搶到了鎖

由於知足flag=x,那麼會執行接下來的for,循序漸進改個flag,而後喚醒被wait的線程(這時候其實沒有),由於執行完一個循環,uniqie_lock會自動釋放鎖,而後子線程和主線程就又開始搶鎖了,此次咱們假設仍是子線程先搶到了鎖,但因爲修改了flag,此時flag!=x,子線程就被阻塞,而後就和狀況(1)差很少啦。

 

 

 

 

【題目2】

編寫一個程序,開啓3個線程,這3個線程的ID分別爲A、B、C,每一個線程將本身的ID在屏幕上打印10遍,要求輸出結果必須按ABC的順序顯示;如:ABCABC….依次遞推。

 

【題解】

其實只要理解了上一題,就是一個套路啦。這裏有所不一樣的是有3個線程,因此最後喚醒條件變量的時候記得用notify_all()。

 

【代碼】

#include<thread> #include<iostream> #include<cstdio> #include<mutex> #include<condition_variable>
using namespace std; int flag = 0; mutex mu; condition_variable cv; void fun(int x) { for (int i = 0; i < 10; i++) { unique_lock<mutex>lock(mu); while (x != flag) cv.wait(lock); cout << static_cast<char>('A' + x) << " "; flag = (flag + 1) % 3; cv.notify_all(); } } int main() { thread t1(fun, 1); thread t2(fun, 2); fun(0); t1.join(); t2.join(); }
View Code
相關文章
相關標籤/搜索