并發(fā)經(jīng)典問題: 哲學(xué)家進餐里烦、吸煙者問題

死鎖四要素:?

?互斥條件: 至少有一個資源不能共享加袋,即一次只能被一個進程/線程占用 ??

?占用和等待: ?一個進程/線程持有資源A并且等待其他進程釋放資源B。 ?

? 非搶占: 一個進程/線程不能無緣無故從另一個進程/線程搶占資源薄扁,只能等待其使用完資源之后自動釋放 ? ?

??循環(huán)等待: 一組進程/線程形成一種循環(huán)等待資源的關(guān)系。每個進程/線程都在等待下一個進程/線程所持有的資源废累。 ? ? ??

????避免死鎖只要破壞上面任何一個條件即可邓梅。

哲學(xué)家進餐問題描述:

?哲學(xué)家進餐問題是一個經(jīng)典的并發(fā)編程問題,描述了五位哲學(xué)家圍坐在圓桌前九默,每人面前放著一碗意大利面和一只叉子震放。他們只有在兩只叉子都拿到手才能吃意大利面,吃完后才能放下叉子繼續(xù)思考驼修。問題是如何設(shè)計算法殿遂,使得哲學(xué)家們能夠正確地進餐而不發(fā)生死鎖(每個哲學(xué)家都在等待右邊的叉子)或饑餓(某些哲學(xué)家始終無法拿到叉子)的情況。

? 方案一: 限制同時吃飯人數(shù)避免死鎖乙各,對應(yīng)打破死鎖的循環(huán)等待這個必要條件墨礁。

? ?為什么限制同時吃飯人數(shù)可以避免死鎖?

? ?根據(jù)抽屜原理: ?K = N * (R) + 1 // K 是資源數(shù)耳峦, N 進程數(shù)恩静,R 是每個進程需要獲取的資源數(shù)量

? ?資源數(shù)量大于需求數(shù)量,必然有一個哲學(xué)家可以拿到2個筷子進餐。打破死鎖必要條件:循環(huán)等待(壓根不用循環(huán))

????哲學(xué)家問題 K = 5 驶乾,R = 1 得出 N = 4邑飒,即同時允許四個哲學(xué)家線程用餐, 至于能否用餐還是看筷子的互斥鎖。

? ? 主要代碼實現(xiàn):

pthread_mutex_t forks[NUM_PHILOSOPHERS]; //每個叉子資源訪問的互斥鎖

sem_t *max_philosophers; //限制同時最多哲學(xué)家進餐人數(shù)

//最多支持NUM_PHILOSOPHERS - 1,個人用餐级乐,抽屜原理可知 最少有一個人手上會拿到兩把叉子 max_philosophers = sem_open("max_philosophers", O_CREAT | O_EXCL, 0666, NUM_PHILOSOPHERS - 1);

static void *philosopher(void *arg) {

? ? int i = *(int *)arg; //當(dāng)前哲學(xué)家編號

? ? int leftFork = (i + NUM_PHILOSOPHERS - 1) % NUM_PHILOSOPHERS;

? ? int rightFork = (i + 1) % NUM_PHILOSOPHERS;

? ? while (1)

? ? {

? ? ? ? sem_wait(max_philosophers);

? ? ? ? printf("Philosopher %d is thinking.\n", i);

? ? ? ? pthread_mutex_lock(&forks[leftFork]);

? ? ? ? pthread_mutex_lock(&forks[rightFork]);

? ? ? ? printf("Philosopher %d is eating.\n", i);

? ? ? ? sleep(1);

? ? ? ? pthread_mutex_unlock(&forks[leftFork]);

? ? ? ? pthread_mutex_unlock(&forks[rightFork]);

? ? ? ? sem_post(max_philosophers);

? ? ? ? sleep(1);

? ? }

? ? return NULL;

}

方案二: 根據(jù)哲學(xué)家編碼奇偶按照不同順序獲取不同的筷子. 打破互斥和循環(huán)條件疙咸,搶占和等待條件也占了點邊。

主要代碼:

#define NUM_PHILOSOPHERS 5

pthread_mutex_t forks[NUM_PHILOSOPHERS]; //叉子的互斥鎖

//拿起筷子

void pickup_forks(int leftfork, int rightfork, int philosopher_id) {

? ? pthread_mutex_lock(&forks[leftfork]);

? ? pthread_mutex_lock(&forks[rightfork]);

? ? printf("Philosopher %d is eating.\n", philosopher_id);

}

//放下筷子

void return_forks(int leftfork, int rightfork) {

? ? pthread_mutex_unlock(&forks[leftfork]);

? ? pthread_mutex_unlock(&forks[rightfork]);

}

static void *philosopher(void *arg) {

? ? int i = *(int *)arg;

? ? int leftfork = (i + NUM_PHILOSOPHERS - 1) % NUM_PHILOSOPHERS;

? ? int rightfork = (i + 1) % NUM_PHILOSOPHERS;

? ? while (1)

? ? {

? ? ? ? if (i % 2 == 0) {

? ? ? ? ? ? pickup_forks(leftfork, rightfork, i);

? ? ? ? } else {

? ? ? ? ? ? pickup_forks(rightfork, leftfork, i);

? ? ? ? }

? ? ? ? sleep(1);

? ? ? ? return_forks(leftfork, rightfork);

? ? ? ? sleep(1);

? ? }

? ? return NULL;

}

非搶占 條件就不舉例了:

????因為一旦涉及到非搶占风科,必然會引入線程優(yōu)先級的問題撒轮,比如A哲學(xué)家的線程優(yōu)先級高但是資源被優(yōu)先級低的B哲學(xué)家線程搶占,那么系統(tǒng)調(diào)度會讓B釋放,讓給A贼穆。如果A頻繁的吃题山,B 線程哲學(xué)家總有一天會被餓死。A 也會被活活撐死故痊。顶瞳。。


吸煙者問題描述:

?三個吸煙者在一個房間內(nèi)崖蜜,還有一個香煙供應(yīng)者浊仆。為了制造并抽掉香煙,每個吸煙者需要三樣?xùn)|西:煙草豫领、紙和火柴抡柿,供應(yīng)者有豐富貨物提供。 三個吸煙者中等恐,第一個有自己的煙草洲劣,第二個有自己的紙,第三個有自己的火柴课蔬。 供應(yīng)者隨機地將兩樣不同的東西放在桌子上囱稽,允許一個吸煙者進行對健康不利的吸煙。 當(dāng)吸煙者完成吸煙后喚醒供應(yīng)者二跋,供應(yīng)者再隨機地把兩樣不同的東西放在桌子上战惊,喚醒一個吸煙者。

這里核心問題就是一個: 當(dāng)前抽煙者手里拿的資源扎即,然后這個資源準(zhǔn)備好之后吞获,讓供應(yīng)者釋放資源信號。所以互斥的信號量是當(dāng)前抽煙人手里的資源谚鄙,而不是另外兩種資源各拷。當(dāng)初看這個問題時候總是會被另外兩個資源印象。這個思路是不對的

代理商放資源需要抽煙者線程激活闷营。抽煙者線程也靠代理商當(dāng)前手里的資源激活烤黍,形成互斥。

吸煙者問題 理解之后實現(xiàn)比較簡單,代碼就不貼了速蕊。有興直接去翻源碼即可嫂丙。


具體源碼在github:?https://github.com/lshdfp726/concurrentServer.git ? 使用C實現(xiàn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末互例,一起剝皮案震驚了整個濱河市奢入,隨后出現(xiàn)的幾起案子筝闹,更是在濱河造成了極大的恐慌媳叨,老刑警劉巖释移,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漩怎,死亡現(xiàn)場離奇詭異,居然都是意外死亡冷蚂,警方通過查閱死者的電腦和手機议双,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門痘番,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人平痰,你說我怎么就攤上這事汞舱。” “怎么了宗雇?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵昂芜,是天一觀的道長。 經(jīng)常有香客問我赔蒲,道長泌神,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任舞虱,我火速辦了婚禮欢际,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘矾兜。我一直安慰自己损趋,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布椅寺。 她就那樣靜靜地躺著浑槽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪配并。 梳的紋絲不亂的頭發(fā)上括荡,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機與錄音溉旋,去河邊找鬼畸冲。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的邑闲。 我是一名探鬼主播算行,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼苫耸!你這毒婦竟也來了州邢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤褪子,失蹤者是張志新(化名)和其女友劉穎量淌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嫌褪,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡呀枢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了笼痛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片裙秋。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖缨伊,靈堂內(nèi)的尸體忽然破棺而出摘刑,到底是詐尸還是另有隱情,我是刑警寧澤刻坊,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布枷恕,位于F島的核電站,受9級特大地震影響紧唱,放射性物質(zhì)發(fā)生泄漏活尊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一漏益、第九天 我趴在偏房一處隱蔽的房頂上張望蛹锰。 院中可真熱鬧,春花似錦绰疤、人聲如沸铜犬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽癣猾。三九已至,卻和暖如春余爆,著一層夾襖步出監(jiān)牢的瞬間纷宇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工蛾方, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留像捶,地道東北人上陕。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像拓春,于是被迫代替她去往敵國和親释簿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容