Linux IPC实践(12) --System V信号量(2)
生活随笔
收集整理的這篇文章主要介紹了
Linux IPC实践(12) --System V信号量(2)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
實(shí)踐1:信號(hào)量實(shí)現(xiàn)進(jìn)程互斥
父子進(jìn)程執(zhí)行流程如下:
父進(jìn)程 | 子進(jìn)程 |
P | P |
O(print) | X(print) |
sleep | sleep |
O(print) | X(print) |
V | V |
sleep | sleep |
從圖中可以看出,?O或X總是成對(duì)出現(xiàn)的,?要么兩個(gè)O,?要么兩個(gè)X;
/**P,V原語(yǔ)實(shí)現(xiàn)父子進(jìn)程互斥使用終端**/ // 程序代碼 int main(int argc,char *argv[]) {int semid = sem_create(IPC_PRIVATE);sem_setval(semid, 1);int count = 10;pid_t pid = fork();if (pid == -1)err_exit("fork error");else if (pid > 0) //子進(jìn)程{srand(getpid());while (count --){sem_P(semid);//臨界區(qū)開(kāi)始cout << 'X';fflush(stdout); //一定要加上ffflush, 因?yàn)橹袛嗍切芯彌_的sleep(rand()%3);cout << 'X';fflush(stdout);//臨界區(qū)結(jié)束sem_V(semid);sleep(rand()%3);}}else //父進(jìn)程{srand(getpid());while (count --){sem_P(semid);//臨界區(qū)開(kāi)始cout << 'O';fflush(stdout);sleep(rand()%3);cout << 'O';fflush(stdout);//臨界區(qū)結(jié)束sem_V(semid);sleep(rand()%3);}wait(NULL);sem_delete(semid);}return 0; }實(shí)踐2:?信號(hào)量集解決哲學(xué)家進(jìn)餐問(wèn)題
? ?假設(shè)有五位哲學(xué)家圍坐在一張圓形餐桌旁,做以下兩件事情之一:吃飯,或者思考。吃東西的時(shí)候,他們就停止思考,思考的時(shí)候也停止吃東西。每?jī)蓚€(gè)哲學(xué)家之間有一只餐叉。因?yàn)橛靡恢徊筒婧茈y吃飯,所以假設(shè)哲學(xué)家必須用兩只餐叉吃東西,?而且他們只能使用自己左右手邊的那兩只餐叉。
/** 解決的方法采用的是: 只有左右兩個(gè)刀叉都能夠使用時(shí),才拿起兩個(gè)刀叉 實(shí)現(xiàn)了有死鎖和無(wú)死鎖的兩種形式的wait_2fork(見(jiàn)下) **/int semid; //沒(méi)有死鎖的wait void wait_2fork(unsigned short no) {unsigned short left = no;unsigned short right = (no+1)%5;struct sembuf sops[2] = {{left, -1, 0}, {right, -1, 0}};//同時(shí)獲取左右兩把刀叉if (semop(semid, sops, 2) == -1)err_exit("wait_2fork error"); } /* //有死鎖的wait void wait_2fork(unsigned short no) {unsigned short left = no;unsigned short right = (no+1)%5;struct sembuf sops = {left, -1, 0};//獲取左邊的刀叉if (semop(semid, &sops, 1) == -1)err_exit("wait_2fork error");sleep(4); //沉睡幾秒, 加速死鎖的產(chǎn)生sops.sem_num = right;//獲取右邊的刀叉if (semop(semid, &sops, 1) == -1)err_exit("wait_2fork error"); } */ //釋放兩把刀叉 void signal_2fork(unsigned short no) {unsigned short left = no;unsigned short right = (no+1)%5;struct sembuf sops[2] = {{left, 1, 0}, {right, 1, 0}};if (semop(semid, sops, 2) == -1)err_exit("signal_2fork error"); } //哲學(xué)家 void philosopher(unsigned short no) {srand(time(NULL));while (true){cout << no << " is thinking" << endl;sleep(rand()%5+1);cout << no << " is hunger" << endl;wait_2fork(no); //獲取兩把刀叉//進(jìn)餐cout << "++ " << no << " is eating" << endl;sleep(rand()%5+1);signal_2fork(no);//釋放兩把刀叉} } int main() {// 創(chuàng)建一個(gè)信號(hào)量集: 里面包含5個(gè)信號(hào)量semid = semget(IPC_PRIVATE, 5, IPC_CREAT|0666);if (semid == -1)err_exit("semget error");//將每個(gè)信號(hào)量都設(shè)初值為1union semun su;su.val = 1;for (int i = 0; i < 5; ++i)if (semctl(semid, i, SETVAL, su) == -1)err_exit("semctl SETVAL error");//創(chuàng)建四個(gè)子進(jìn)程, 將每個(gè)進(jìn)程的編號(hào)設(shè)定為nopid_t pid;unsigned short no = 0;for (unsigned short i = 0; i < 4; ++i){pid = fork();if (pid == -1)err_exit("fork error");else if (pid == 0){no = i+1;break;}}// 最后五個(gè)進(jìn)程(4個(gè)子進(jìn)程+1個(gè)父進(jìn)程)都會(huì)匯集到此處,// 每個(gè)進(jìn)程代表著一個(gè)哲學(xué)家,編號(hào)no: 0~4philosopher(no);return 0; }新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎(jiǎng)!定制產(chǎn)品紅包拿不停!
總結(jié)
以上是生活随笔為你收集整理的Linux IPC实践(12) --System V信号量(2)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Zernike函数拟合曲面--MATLA
- 下一篇: LAMP(linux下apache+my