在linux環(huán)境下,巧妙運(yùn)用信號(hào)量解決水果放取問題,這是一個(gè)有趣且實(shí)用的多線程同步問題。以下是該問題的思維導(dǎo)圖、代碼演示和思路解析。
一. 信號(hào)量相關(guān)實(shí)驗(yàn)回顧
-
回顧:使用信號(hào)量實(shí)現(xiàn)線程互斥
- 解析:利用信號(hào)量實(shí)現(xiàn)兩個(gè)線程互斥輸出1-10數(shù)字。
- 傳送門
-
回顧:巧妙運(yùn)用信號(hào)量控制兩個(gè)線程之間誰先執(zhí)行
-
回顧:巧妙運(yùn)用信號(hào)量實(shí)現(xiàn)線程間通信
二. 巧妙運(yùn)用信號(hào)量解決水果放取問題(思維導(dǎo)圖&代碼演示&思路解析)
問題描述:一個(gè)盤子只能放一個(gè)水果,爸爸往里面放蘋果,媽媽往里面放橘子,兒子專門等吃橘子,女兒專門等吃蘋果。只要盤子空,爸爸或媽媽就可以往里面放水果;僅當(dāng)盤子里有自己需要的水果時(shí),兒子或女兒才可以取出吃。
設(shè)置三個(gè)信號(hào)量:
- plate:初始值為1,優(yōu)先執(zhí)行,面向父母端。
- appleReady:初始值為0,對(duì)應(yīng)女兒等待蘋果。
- orangeReady:初始值為0,對(duì)應(yīng)兒子等待橘子。
定義:
- fruitOnPlate:表示盤子中是否有水果。
- fruitType:表示盤子中水果的類型。
- https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15bdefine APPLE 1 和 https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15bdefine ORANGE 2:表示水果類型。
信號(hào)量操作:
- 信號(hào)量等待(P操作):sem_wait()
- 信號(hào)量喚醒(V操作):sem_post()
代碼語言:C
運(yùn)行次數(shù):0
https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15binclude <stdio.h> https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15binclude <stdlib.h> https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15binclude <pthread.h> https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15binclude <semaphore.h> https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15binclude <unistd.h> https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15bdefine APPLE 1 https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15bdefine ORANGE 2 // 表示放入水果 int fruitOnPlate = 0; int fruitType = 0; // 設(shè)置信號(hào)量 sem_t plate, appleReady, orangeReady; void *father(void *arg) { while (1) { sem_wait(&plate); fruitOnPlate = 1; fruitType = APPLE; // 放入蘋果 printf("Father put an apple.n"); sem_post(&appleReady); sleep(rand() % 10); // 睡眠隨機(jī)時(shí)間 } } void *mother(void *arg) { while (1) { sem_wait(&plate); fruitOnPlate = 1; fruitType = ORANGE; // 放入橘子 printf("Mother put an orange.n"); sem_post(&orangeReady); sleep(rand() % 10); // 睡眠隨機(jī)時(shí)間 } } void *son(void *arg) { while (1) { sem_wait(&orangeReady); // 等待橘子 if (fruitType == ORANGE) { printf("Son ate an orange.n"); sem_post(&plate); } } } void *daughter(void *arg) { while (1) { sem_wait(&appleReady); // 等待蘋果 if (fruitType == APPLE) { printf("Daughter ate an apple.n"); sem_post(&plate); } } } int main() { pthread_t f_thread, m_thread, son_thread, dau_thread; sem_init(&plate, 0, 1); sem_init(&appleReady, 0, 0); sem_init(&orangeReady, 0, 0); pthread_create(&f_thread, NULL, father, NULL); pthread_create(&m_thread, NULL, mother, NULL); pthread_create(&son_thread, NULL, son, NULL); pthread_create(&dau_thread, NULL, daughter, NULL); pthread_join(f_thread, NULL); pthread_join(m_thread, NULL); pthread_join(son_thread, NULL); pthread_join(dau_thread, NULL); sem_destroy(&plate); sem_destroy(&appleReady); sem_destroy(&orangeReady); return 0; }
通過以上代碼,我們可以看到信號(hào)量的巧妙運(yùn)用,確保了水果放取的正確性和同步性。
? 版權(quán)聲明
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載。
THE END