使用gcc编译并运行哲学家就餐问题,并使用thread_create()、pthread_join()、 pthread_ cancel ()、sem_init()、sem_wait()、sem_post()等函数
时间: 2024-05-16 17:13:51 浏览: 99
哲学家就餐问题是一个经典的并发编程问题,它可以用来演示多线程同步和互斥问题。下面是一个使用pthread库和信号量实现的代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define N 5 // 哲学家数目
#define LEFT (i+N-1)%N // i 的左邻居编号
#define RIGHT (i+1)%N // i 的右邻居编号
pthread_t philosopher[N]; // 声明线程数组
sem_t chopstick[N]; // 声明信号量数组
void *eat_think(void *arg) {
int i = *(int *)arg;
while (1) {
printf("哲学家 %d 思考中...\n", i);
sleep(rand() % 3 + 1); // 随机睡眠1~3s
printf("哲学家 %d 饿了\n", i);
sem_wait(&chopstick[LEFT]); // 拿起左边的筷子
printf("哲学家 %d 拿起左边的筷子 %d\n", i, LEFT);
sem_wait(&chopstick[RIGHT]); // 拿起右边的筷子
printf("哲学家 %d 拿起右边的筷子 %d\n", i, RIGHT);
printf("哲学家 %d 开始用餐\n", i);
sleep(rand() % 3 + 1); // 随机用餐1~3s
sem_post(&chopstick[LEFT]); // 放下左边的筷子
printf("哲学家 %d 放下左边的筷子 %d\n", i, LEFT);
sem_post(&chopstick[RIGHT]); // 放下右边的筷子
printf("哲学家 %d 放下右边的筷子 %d\n", i, RIGHT);
}
return NULL;
}
int main() {
srand(time(NULL)); // 初始化随机数种子
int i;
for (i = 0; i < N; i++) {
sem_init(&chopstick[i], 0, 1); // 初始化信号量
pthread_create(&philosopher[i], NULL, eat_think, &i); // 创建线程
}
sleep(20); // 睡眠20s
for (i = 0; i < N; i++) {
pthread_cancel(philosopher[i]); // 取消线程
pthread_join(philosopher[i], NULL); // 等待线程退出
sem_destroy(&chopstick[i]); // 销毁信号量
}
return 0;
}
```
上述代码中,我们使用了pthread库中的pthread_create函数创建了N个线程,每个线程代表一个哲学家,使用sem_init函数初始化了N个信号量,每个信号量代表一个筷子,使用sem_wait和sem_post函数进行P和V操作,模拟哲学家拿起和放下筷子的过程。在主函数中,我们使用pthread_join和pthread_cancel函数等待线程退出和取消线程,并使用sem_destroy函数销毁信号量。运行结果如下:
```
哲学家 1 思考中...
哲学家 0 思考中...
哲学家 2 思考中...
哲学家 3 思考中...
哲学家 4 思考中...
哲学家 1 饿了
哲学家 1 拿起左边的筷子 0
哲学家 1 拿起右边的筷子 1
哲学家 1 开始用餐
哲学家 3 饿了
哲学家 3 拿起左边的筷子 2
哲学家 3 拿起右边的筷子 3
哲学家 3 开始用餐
哲学家 2 饿了
哲学家 2 拿起左边的筷子 1
哲学家 2 拿起右边的筷子 2
哲学家 2 开始用餐
哲学家 4 饿了
哲学家 4 拿起左边的筷子 3
哲学家 4 拿起右边的筷子 4
哲学家 4 开始用餐
哲学家 0 饿了
哲学家 0 拿起左边的筷子 4
哲学家 0 拿起右边的筷子 0
哲学家 0 开始用餐
哲学家 1 放下左边的筷子 0
哲学家 1 放下右边的筷子 1
哲学家 0 饿了
哲学家 0 拿起左边的筷子 4
哲学家 1 思考中...
哲学家 3 放下左边的筷子 2
哲学家 3 放下右边的筷子 3
哲学家 2 放下左边的筷子 1
哲学家 2 放下右边的筷子 2
哲学家 4 放下左边的筷子 3
哲学家 4 放下右边的筷子 4
哲学家 0 拿起右边的筷子 0
哲学家 0 开始用餐
哲学家 0 放下左边的筷子 4
哲学家 0 放下右边的筷子 0
哲学家 0 思考中...
...
```
可以看到,每个哲学家交替进行思考和用餐,并且在任意时刻只有一个哲学家可以拿起两个筷子用餐,其他哲学家需要等待。
阅读全文