# 2. 给出伪代码

5位哲学家与左右邻居对其中间筷子的访问时互斥关系，但与之前遇到的问题不同的是，每个哲学家进程需要同时持有两个临界资源才能开始吃饭，因此要避免临界资源分配不当造成的死锁现象。

通过互斥信号量mutex对eat()之前取左侧和右侧筷子的操作进行保护，可以防止死锁的出现。

semaphore mutex=1；//互斥地取筷子

semaphore chopstick[5]={1,1,1,1,1}

void philosopher (int i){ //i号哲学家的进程

while（true）{

think();

wait(cjopstick[i]);

wait(chopstick[(i+1)mod 5]);

signal(mutex);

eat();

signal(chopstick[(i+1)mod 5]);

signal(chopstick[i]);

think();

}

}

# 3. 给出完整代码

#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>
#include<unistd.h>
#include<errno.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/wait.h>

#define ERR_EXIT(m) \
do { \
perror(m); \
exit(EXIT_FAILURE); \
} while(0)

union semun
{
int val;    /* Value for SETVAL */
struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
unsigned short  *array;  /* Array for GETALL, SETALL */
struct seminfo  *__buf;  /* Buffer for IPC_INFO (Linux-specific) */
};

int semid;

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

void wait_for_2fork(int no)
{
int left = no;
int right = (no + 1) % 5;

struct sembuf buf[2] =
{
{left, -1, 0},
{right, -1, 0}
};

semop(semid, buf, 2);
}

void free_2fork(int no)
{
int left = no;
int right = (no + 1) % 5;

struct sembuf buf[2] =
{
{left, 1, 0},
{right, 1, 0}
};

semop(semid, buf, 2);
}

void philosopere(int no)
{
srand(getpid());
for (; ;)
{

printf("%d is thinking\n", no);
sleep(DELAY);
printf("%d is hungry\n", no);
wait_for_2fork(no);
printf("%d is eating\n", no);
sleep(DELAY);
free_2fork(no);
}
}

int main(void)
{

semid = semget(IPC_PRIVATE, 5, IPC_CREAT | 0666);
if (semid == -1)
ERR_EXIT("semget");
union semun su;
su.val = 1;
int i;
for (i = 0; i < 5; i++)
{
semctl(semid, i, SETVAL, su);
}

int no = 0;
pid_t pid;
for (i = 1; i < 5; i++)
{
pid = fork();
if (pid == -1)
ERR_EXIT("fork");

if (pid == 0)
{
no = i;
break;
}
}

philosopere(no);

return 0;
}

# 4. 运行结果并解释

### 结果解释：

posted on 2020-05-29 16:36  霓袅  阅读(199)  评论(0编辑  收藏  举报