ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

操作系统第6次实验报告:使用信号量解决进程互斥访问

2020-05-29 22:57:49  阅读:346  来源: 互联网

标签:no int 叉子 信号量 互斥 tk fno sem 实验报告


  • 姓名:杨富宏
  • 学号:201821121017
  • 班级:计算1811

1. 哲学家进餐问题

   五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在桌子上有五只碗和五只筷子,他们的生活方式是交替地进行思考和进餐。

平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐毕,放下筷子继续思考。

2. 给出伪代码

void philosopher(int i)    // i:哲学家编号,从0到4
{
    while(TRUE)
    {
        think();                 // 哲学家思考
        take_fork(i);         //饿了,拿起左叉子
        take_fork((i+1)%N);  // 拿起右叉子
        eat();                     // 进食
        put_fork(i);          // 放下左叉子
        put_fork((i+1)%N);  // 放下右叉子
    }
}

可以保证不会有两个相邻的哲学家同时进餐,但却可能引起死锁的情况。假如五位哲学家同时饥饿而都拿起的左边的叉子,

就会使五个信号量fork都为0,当他们试图去拿右手边的叉子时,都将无叉子而陷入无限期的等待。因此出现了死锁问题。

解决:上面造成死锁是因为五个哲学家都拿起一边的叉子,而另一边的却没有拿到,继而一直等待着另外一边。

这样解决的办法就是哲学家必须同时拿起左右两边的叉子,这样可以保证每一次都有两个不相邻的哲学家同时进餐。

3. 给出完整代码

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<sys/ipc.h>
  4 #include<sys/msg.h>
  5 #include<sys/types.h>
  6 #include<unistd.h>
  7 #include<errno.h>
  8 #include<sys/ipc.h>
  9 #include<sys/sem.h>
 10 #include<sys/wait.h>
 11
 12 #define SEMS_NUM 5  //信号量数目
 13 #define THINKER_NUM 5 //哲学家人数
 14 #define FORK_NUM 5 //叉子数
 15 #define TIME_WAIT (rand() % 5 + 1) //等待时间
 16
 17 union semun
 18 {
 19 int val;    //SETVAL用的值
 20 struct semid_ds *buf;  //IPC_STAT、IPC_SET用的semid_ds结构
 21 unsigned short  *array; //SETALL、GETALL用的数组值
 22 struct seminfo  *__buf; //为控制IPC_INFO提供的缓存
 23 };
 24
 25 #define ERR_EXIT(m) \
 26 do { \
 27 perror(m); \
 28 exit(EXIT_FAILURE); \
 29 } while(0)
 30
 31 void P(int sem_id,int left_fno,int right_fno)
 32 {
 33 struct sembuf sbuf[2] =
 34 {
 35 {left_fno, -1, SEM_UNDO},
 36 {right_fno, -1, SEM_UNDO}
 37 };
 38
 39 if(semop(sem_id, sbuf, 2) == -1) {
 40 ERR_EXIT("P");
 41 }
 42 }
 43 /*对信号量数组编号为no的信号量做V操作
 44 哲学家放回叉子
 45 */
 46 void V(int sem_id,int left_fno,int right_fno){
 46 void V(int sem_id,int left_fno,int right_fno){
 47
 48 /*
 49 sbuf.sem_num:序号
 50 sbuf.sem_op:操作,1表示V操作
 51 sem_flg:设置信号量的操作
 52 */
 53 struct sembuf sbuf[2] =
 54 {
 55 {left_fno, 1, SEM_UNDO},
 56 {right_fno, 1, SEM_UNDO}
 57 };
 58
 59 if(semop(sem_id, sbuf, 2) == -1) {
 60 ERR_EXIT("V");
 61 }
 62 }
 63 void think(int tk_no){
 64 printf("Philosopher %d is thinking\n", tk_no);
 65 sleep(TIME_WAIT);
 66 }
 67
 68 void eat(int tk_no){
 69 printf("Philosopher %d is eating\n", tk_no);
 70 sleep(TIME_WAIT);
 71 }
 72
 73 void hungry(int tk_no){
 74 printf("Philosopher %d is hungry\n", tk_no);
 75 }
 76
 77 void philosopere(int sem_id,int tk_no)
 78 {
 79 srand(getpid());
 80 int left_fno=tk_no; //left_fno左边叉子编号
 81 int right_fno=(left_fno+1)%FORK_NUM;
 82 while(1)
 83 {
 84 think(tk_no);//思考
 85 hungry(tk_no);//饥饿
 86 //拿取一双叉子
 87 P(sem_id,left_fno,right_fno);
 88 eat(tk_no);//就餐
 89 //放下叉子
 90 V(sem_id,left_fno,right_fno);
 91 }
 92 }
 93 int main()
 94 {
 95 //1.创建 Semaphore(计数信号量)
 96 //创建信号集,其中有SEMS_NUM个信号量
 97 int sem_id = semget(IPC_PRIVATE, SEMS_NUM, IPC_CREAT | 0666);
 98 if (sem_id == -1){
 99 ERR_EXIT("semget");
100 }
101
102 //2.初始化 Semaphore
103 union semun sem;
104 sem.val = 1;
105 int i;
106 for (i = 0; i < SEMS_NUM; i++){
107 if(semctl(sem_id, i, SETVAL, sem)==-1){
108 ERR_EXIT("semctl");
109 }
110 }
111
112 int tk_no = 0;//哲学家编号
113 pid_t pid;
114 //创建子进程
115 for (i = 1; i < THINKER_NUM; i++)
116 {
117 pid = fork();
118 if (pid == -1){
119 ERR_EXIT("fork");
120 }
121 if (pid == 0){
122 tk_no = i;
123 break;
124 }
125 }
126
127 philosopere(sem_id,tk_no);//处理就餐
128
129 return 0;
130 }

4. 运行结果并解释

 结果解释:

  本题有五个进程,对应着五个哲学家。首先哲学家进行思考,接着就是饥饿,最后哲学家同时拿起两边的叉子进餐,

每一轮只有两位哲学家能够进餐,另外三位需要等待,并且这两位哲学家不能相邻,实验结果中首先是一号和四号哲学

家先进餐,这两个哲学家并不相邻。结果表示哲学家的进餐过程没有停,解决了上面的死锁问题。

 

参考文献:https://blog.csdn.net/qq_28602957/article/details/53538329

标签:no,int,叉子,信号量,互斥,tk,fno,sem,实验报告
来源: https://www.cnblogs.com/yangfuhong/p/12989971.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有