操作系统第6次实验报告:使用信号量解决进程互斥访问
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了操作系统第6次实验报告:使用信号量解决进程互斥访问,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4808字,纯文字阅读大概需要7分钟。
内容图文
![操作系统第6次实验报告:使用信号量解决进程互斥访问](/upload/InfoBanner/zyjiaocheng/938/a4276e8c12dc4d45b9cd28172aa41565.jpg)
- 姓名:林永鑫
- 学号:201821121040
- 班级:计算1812
1. 选择哪一个问题
选题哪个问题?
- 生产者-消费者问题
- 读者-写者问题
- 哲学家进餐问题
选择哲学家进餐问题
关于此问题:
有五个哲学家,他们的生活方式是交替地进行思考和进餐,哲学家们共用一张圆桌,分别坐在周围的五张椅子上, 在圆桌上有五个碗和五支筷子,平时哲学家进行思考,饥饿时便试图取其左、右最靠近他的筷子,只有在他拿到 两支筷子时才能进餐,该哲学家进餐完毕后,放下左右两只筷子又继续思考。 约束条件 (1)只有拿到两只筷子时,哲学家才能吃饭。 (2)如果筷子已被别人拿走,则必须等别人吃完之后才能拿到筷子。 (3)任一哲学家在自己未拿到两只筷子吃完饭前,不会放下手中已经拿到的筷子。2. 给出伪代码
程序中,哲学家编号为0到4,筷子编号也为0到4且与哲学家编号相同的筷子位于该哲学家左侧。
为了解决死锁的问题:仅当哲学家左右两侧的筷子都可用时,才允许他一次性同时拿起两只筷子。
semaphore chopstick chopstick[5] = {1,1,1,1,1}; do { //think Sswait(chopstick[i],chopstick[(i+1)%5]); //eat Ssignal(chopstick[i],chopstick[(i+1)%5]); }while(true)
3. 给出完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <stdbool.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/wait.h> union semun { int val; struct semid_ds *buf; unsigned short *array; struct seminfo *__buf; }; #define ERR_EXIT(m) \ do { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) //申请一个资源 int wait_1fork(int no,int semid) { //int left = no; //int right = (no + 1) % 5; struct sembuf sb = {no,-1,0}; int ret; ret = semop(semid,&sb,1); if(ret < 0) { ERR_EXIT("semop"); } return ret; } // 释放一个资源 int free_1fork(int no,int semid) { struct sembuf sb = {no,1,0}; int ret; ret = semop(semid,&sb,1); if(ret < 0) { ERR_EXIT("semop"); } return ret; } //这里表明叉子是一个临界资源 #define DELAY (rand() % 5 + 1) //相当于P操作 void wait_for_2fork(int no,int semid) { //哲学家左边的刀叉编号和哲学家是一样的 int left = no; //右边的刀叉 int right = (no + 1) % 5; //刀叉值是两个 //注意第一个参数是编号 //操作的是两个信号量,即两种资源都满足,才进行操作 struct sembuf buf[2] = { {left,-1,0}, {right,-1,0} }; //信号集中有5个信号量,只是对其中的资源sembuf进行操作 semop(semid,buf,2); } //相当于V操作 ,释放刀叉 void free_2fork(int no,int semid) { int left = no; int right = (no + 1) % 5; struct sembuf buf[2] = { {left,1,0}, {right,1,0} }; semop(semid,buf,2); } //哲学家要做的事 void philosophere(int no,int semid) { srand(getpid()); //srand(time(NULL)); for(;;) { #if 1 //这里采取的措施是当两把刀叉都可用的时候(即两种资源都满足的时候) //哲学家才能吃饭,这样不相邻的哲学家就可吃上饭 printf("%d is thinking\n",no); // 思考中 sleep(DELAY); printf("%d is hungry\n",no); // 感觉到饥饿 wait_for_2fork(no,semid);//拿到两把叉子才能吃饭 printf("%d is eating\n",no); // 吃饭 sleep(DELAY); free_2fork(no,semid);//释放两把叉子 #else //这段代码可能会造成死锁 int left = no; int right = (no + 1) % 5; printf("%d is thinking\n",no); // 思考中 sleep(DELAY); printf("%d is hungry\n",no); // 感觉到饥饿 wait_1fork(left,semid); // 拿起左叉子,现在是只要有一个资源,就申请 sleep(DELAY); wait_1fork(right,semid); // 拿到右叉子 printf("%d is eating\n",no); // 吃饭 sleep(DELAY); free_1fork(left,semid); // 释放左叉子 free_1fork(right,semid); // 释放右叉子 #endif } } int main(int argc,char *argv[]) { int semid; //创建信号量 //信号量集中5个信号量 semid = semget(IPC_PRIVATE,5,IPC_CREAT | 0666); if(semid < 0) { ERR_EXIT("semid"); } union semun su; su.val = 1; int i; for(i = 0;i < 5;++i) { //注意第二个参数也是索引 semctl(semid,i,SETVAL,su); } //创建4个子进程 int num = 0; pid_t pid; for(i = 1;i < 5;++i) { pid = fork(); if(pid < 0) { ERR_EXIT("fork"); } if(0 == pid) // 子进程 { num = i; break; } } //这里就是哲学家要做的事情 philosophere(num,semid); return 0; }
4. 运行结果并解释
运行结果:代码一直运行,不停止。说明没有出现死锁
第一行到第五行:5位哲学家都在思考中
第六行到第七行:编号为3的哲学家饿了,此时该哲学家左右两侧的筷子都可用,他一次性同时拿起两只筷子,开始进食
第八行:编号为2的哲学家饿了,此时该哲学家右侧的筷子被编号为3的哲学家使用中,所以该哲学家保持饥饿
第九行:编号为0的哲学家饿了,此时该哲学家左右两侧的筷子都可用,他一次性同时拿起两只筷子,开始进食
第十行:编号为4的哲学家饿了,此时该哲学家左侧的筷子被编号为3的哲学家使用中,所以该哲学家保持饥饿
第十一行:编号为0的哲学家进食结束,恢复思考状态
第十二行到第十三行:编号为1的哲学家饿了,此时该哲学家左右两侧的筷子都可用,他一次性同时拿起两只筷子,开始进食
第十四行到第十五行:编号为3的哲学家进食结束,恢复思考状态。此时编号为4的哲学家左右两侧的筷子都可用,他一次性同时拿起两只筷子,开始进食
第十六行:编号为0的哲学家饿了,此时该哲学家右侧的筷子被编号为1的哲学家使用中,所以该哲学家保持饥饿
第十七行:编号为4的哲学家进食结束,恢复思考状态
第十八行到第十九行:编号为3的哲学家饿了,此时该哲学家左右两侧的筷子都可用,他一次性同时拿起两只筷子,开始进食
第二十行:编号为0的哲学家进食结束,恢复思考状态
内容总结
以上是互联网集市为您收集整理的操作系统第6次实验报告:使用信号量解决进程互斥访问全部内容,希望文章能够帮你解决操作系统第6次实验报告:使用信号量解决进程互斥访问所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。