操作系统实验六

  1. 1. 实验代码
  2. 2. 实验结果
  3. 3. 解决方案中是否出现饥饿?为什么?

同步机制——信号量集与哲学家就餐问题

实验目的:理解Linux系统中基于信号量集的同步机制,并使用该同步机制解决并发进程的同步问题。
实验内容:

  1. 定义5把叉子的信号量集。
  2. 编写5个哲学家的就餐活动,解决哲学家就餐时对叉子资源的申请和释放。
  3. 用fork()系统调用创建5个哲学家进程并使其并发执行,通过观察运行结果判断同步算法的正确性。

实验代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>

union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
}arg;
int semid;
philosopher(int i)
{
int j;
struct sembuf sbuf[2];
sbuf[0].sem_num=i;
sbuf[0].sem_flg=SEM_UNDO;
sbuf[1].sem_num=(i+1)%5;
sbuf[1].sem_flg=SEM_UNDO;
for(j=0;j<5;j++)
{
printf("philosopher %d is thinking\n",i);
sleep(2);
printf("philosopher %d is hungry\n",i);
sbuf[0].sem_op=-1;
sbuf[1].sem_op=-1;
semop(semid,sbuf,2);
printf("philosopher %d is eating\n",i);
sleep(2);
sbuf[0].sem_op=1;
sbuf[1].sem_op=1;
semop(semid,sbuf,2);
}
exit(i);
}

int main(){
int semid,key,pid,status,i;
key=ftok("fname",1);
semid=semget(key,5,IPC_CREAT|0666);
arg.val=1;
for(i=0;i<5;i++)
semctl(semid,i,SETVAL,arg);
for(i=0;i<5;i++)
{
pid=fork();
if(pid==0)
philosopher(i);
}
pid=wait(&status);
}

实验结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
philosopher 0 is thinking
philosopher 1 is thinking
philosopher 2 is thinking
philosopher 3 is thinking
philosopher 4 is thinking
philosopher 0 is hungry
philosopher 1 is hungry
philosopher 2 is hungry
philosopher 4 is hungry
philosopher 0 is eating
philosopher 2 is eating
philosopher 3 is hungry
philosopher 2 is thinking
philosopher 0 is thinking
philosopher 1 is eating
philosopher 4 is eating
philosopher 2 is hungry
philosopher 1 is thinking
philosopher 0 is hungry
philosopher 0 is eating
philosopher 4 is thinking
philosopher 3 is eating
philosopher 1 is hungry
philosopher 4 is hungry
philosopher 0 is thinking
philosopher 1 is eating
philosopher 3 is thinking
philosopher 4 is eating
philosopher 0 is hungry
philosopher 4 is thinking
philosopher 3 is hungry
philosopher 0 is eating
philosopher 1 is thinking
philosopher 2 is eating
philosopher 0 is thinking
philosopher 1 is hungry
philosopher 4 is hungry
philosopher 3 is eating
philosopher 2 is thinking
philosopher 1 is eating
philosopher 0 is hungry
philosopher 3 is thinking
philosopher 1 is thinking
philosopher 2 is hungry
philosopher 2 is eating
philosopher 4 is eating
philosopher 3 is hungry
philosopher 1 is hungry
philosopher 4 is thinking
philosopher 2 is thinking
philosopher 3 is eating
philosopher 0 is eating
philosopher 2 is hungry
philosopher 4 is hungry
philosopher 3 is thinking
philosopher 2 is eating
philosopher 0 is thinking
philosopher 4 is eating
philosopher 3 is hungry
philosopher 2 is thinking
philosopher 0 is hungry
philosopher 4 is thinking
philosopher 1 is eating
philosopher 3 is eating
philosopher 2 is hungry
philosopher 4 is hungry
philosopher 1 is thinking
philosopher 3 is thinking
philosopher 2 is eating
philosopher 0 is eating
philosopher 1 is hungry
philosopher 3 is hungry
philosopher 3 is eating
philosopher 1 is eating

解决方案中是否出现饥饿?为什么?

存在饥饿

当多个哲学家同时饥饿并尝试获取筷子时,可能发生死锁。死锁是指一组进程互相等待对方所持有的资源,导致所有进程都无法继续执行。

在这个代码中,如果每个哲学家都饥饿并尝试获取左右两边的筷子,但同时只有一个筷子可用,那么所有哲学家都会陷入饥饿状态,并且无法解除。这种情况下,每个哲学家都无法获得所需的两个筷子,无法进餐,从而导致饥饿问题的发生。