哲学家就餐问题(避免死锁)
解决方案:
-
策略:奇偶哲学家拿筷子顺序不同,破坏循环等待。
-
流程:
-
偶数哲学家先左后右。
-
奇数哲学家先右后左。
-
分析:
-
无死锁,哲学家交替进餐,不同拿筷顺序避免循环等待。
实验总结
遇到的问题及解决:
-
读者写者写者优先难以实现:通过引入
readTry
信号量,确保写者优先阻塞新读者。 -
哲学家死锁:调整奇偶拿筷顺序,破坏循环等待条件。
心得体会:
-
并发编程需精确控制同步机制,避免竞态和死锁。
-
测试需覆盖多线程竞争场景,调试时输出线程状态有助于定位问题。
测试数据:
-
5个哲学家线程,每个循环5次。
运行结果:
Philosopher 0 is thinking...
Philosopher 1 is thinking...
Philosopher 0 is eating...
Philosopher 2 is eating...
源代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>#define NUM_PHILOSOPHERS 5
#define NUM_LOOP 5sem_t chopsticks[NUM_PHILOSOPHERS];void *philosopher(void *arg) {int id = *(int*)arg;int left = id, right = (id+1) % NUM_PHILOSOPHERS;for (int i = 0; i < NUM_LOOP; i++) {printf("Philosopher %d thinking...\n", id);usleep(1000000);if (id % 2 == 0) {sem_wait(&chopsticks[left]);sem_wait(&chopsticks[right]);} else {sem_wait(&chopsticks[right]);sem_wait(&chopsticks[left]);}printf("Philosopher %d eating...\n", id);usleep(500000);sem_post(&chopsticks[left]);sem_post(&chopsticks[right]);}return NULL;
}int main() {pthread_t phils[NUM_PHILOSOPHERS];int ids[NUM_PHILOSOPHERS];for (int i = 0; i < NUM_PHILOSOPHERS; i++)sem_init(&chopsticks[i], 0, 1);for (int i = 0; i < NUM_PHILOSOPHERS; i++) {ids[i] = i;pthread_create(&phils[i], NULL, philosopher, &ids[i]);}for (int i = 0; i < NUM_PHILOSOPHERS; i++)pthread_join(phils[i], NULL);for (int i = 0; i < NUM_PHILOSOPHERS; i++)sem_destroy(&chopsticks[i]);return 0;
}