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

  • 姓名毛琳淇
  • 学号201821121007
  • 班级计算1811

1. 选择哪一个问题

哲学家进餐问题

2. 给出伪代码

 

semaphore chopstick[5] = {1,1,1,1,1}; 
do{ 
wait(chopstick[i]);  //拿起筷子
wait(chopstick[(i+1)%5]);
eat();//吃饭
signal(chopstick[i]); //释放筷子
signal(chopstick[(i+1)%5]);
think();//思考
 }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)
//将叉子设置为一个临界资源 

#define DELAY (rand() % 5 + 1)

/*拿起两边的刀叉 
采用的方法:仅当一个哲学家左右两边的叉子都可用时才允许他抓起叉子
哲学家才能吃饭,这样不相邻的哲学家就可吃上饭*/ 
void P(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);
}

//释放刀叉
void V(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());
for(;;) 
{
printf("%d号哲学家正在思考\n",no); 
sleep(DELAY);
printf("%d号哲学家等待左右刀叉中\n",no); //饥饿状态 
P(no,semid);//拿到两把叉子才能吃饭
printf("%d号哲学家吃饭中\n",no); // 吃饭
sleep(DELAY);
V(no,semid);//释放两把叉子
}
}
int main(int argc,char *argv[])
{
int semid;
//创建5个信号量代表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. 运行结果并解释

 

 

采用解决死锁的方法:

 哲学家手中刀叉的情况只有两种即没有或者有两个,仅当一个哲学家左右两边的叉子都可用时才允许他抓起叉子。那么哲学家就有三种状态:思考状态不用叉子、饥饿状态在等待左右叉子,吃饭状态正在使用两个叉子。

一共有0-45位哲学家,开始时大家都在思考,4号先进入等待状态后拿到了筷子,2号也进入等待状态并拿到了筷子,1号进入了等待状态但因为2号拿走了1号左手边的筷子所以1号未能拿到筷子进食,4号停止进食进入思考状态,0进入等待状态并拿到了筷子,3号进入了等待状态但因为2号拿走了其右手边的筷子所以未能拿到筷子进食。

 

posted @ 2020-05-29 16:49  my7in7i  阅读(138)  评论(0编辑  收藏  举报