用C语言编程实现P、V原语并用P、V原语描述如下哲学家就餐问题。问题如下:5个哲学家围着圆桌坐全体到达后开始讨论:在讨论的间隙哲学家进餐每人进餐时都需使用一双筷子所有哲学家左右手筷子都拿到后才能进餐。哲学家的人数、餐桌上的布置自行设定实现筷子的互斥使用算法的程序实现要求:1、用5个进程表示5位哲学家为每个哲学家各编一段程序描述他们的行为试用P、V操作实现。2、用一个父进程实现创建5个哲学家的子进程
方法一:使用信号量实现P、V原语
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM_PHILOSOPHERS 5
#define LEFT (i + NUM_PHILOSOPHERS - 1) % NUM_PHILOSOPHERS
#define RIGHT (i + 1) % NUM_PHILOSOPHERS
sem_t forks[NUM_PHILOSOPHERS];
sem_t mutex;
void *philosopher(void *arg) {
int i = *((int *)arg);
while (1) {
printf("Philosopher %d is thinking.\n", i);
sleep(rand() % 3 + 1);
sem_wait(&mutex);
sem_wait(&forks[LEFT]);
sem_wait(&forks[RIGHT]);
printf("Philosopher %d is eating.\n", i);
sleep(rand() % 3 + 1);
sem_post(&forks[RIGHT]);
sem_post(&forks[LEFT]);
sem_post(&mutex);
}
}
int main() {
pthread_t philosophers[NUM_PHILOSOPHERS];
int philosopher_ids[NUM_PHILOSOPHERS];
sem_init(&mutex, 0, 1);
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
sem_init(&forks[i], 0, 1);
}
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
philosopher_ids[i] = i;
pthread_create(&philosophers[i], NULL, philosopher, &philosopher_ids[i]);
}
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_join(philosophers[i], NULL);
}
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
sem_destroy(&forks[i]);
}
sem_destroy(&mutex);
return 0;
}
方法二:使用条件变量实现P、V原语
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_PHILOSOPHERS 5
#define LEFT (i + NUM_PHILOSOPHERS - 1) % NUM_PHILOSOPHERS
#define RIGHT (i + 1) % NUM_PHILOSOPHERS
pthread_mutex_t forks[NUM_PHILOSOPHERS];
pthread_cond_t forks_available[NUM_PHILOSOPHERS];
void *philosopher(void *arg) {
int i = *((int *)arg);
while (1) {
printf("Philosopher %d is thinking.\n", i);
sleep(rand() % 3 + 1);
pthread_mutex_lock(&forks[LEFT]);
pthread_mutex_lock(&forks[RIGHT]);
printf("Philosopher %d is eating.\n", i);
sleep(rand() % 3 + 1);
pthread_mutex_unlock(&forks[RIGHT]);
pthread_mutex_unlock(&forks[LEFT]);
}
}
int main() {
pthread_t philosophers[NUM_PHILOSOPHERS];
int philosopher_ids[NUM_PHILOSOPHERS];
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_mutex_init(&forks[i], NULL);
pthread_cond_init(&forks_available[i], NULL);
}
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
philosopher_ids[i] = i;
pthread_create(&philosophers[i], NULL, philosopher, &philosopher_ids[i]);
}
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_join(philosophers[i], NULL);
}
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_mutex_destroy(&forks[i]);
pthread_cond_destroy(&forks_available[i]);
}
return 0;
}
以上两种方法都实现了筷子的互斥使用,避免了死锁现象
原文地址: https://www.cveoy.top/t/topic/hBPl 著作权归作者所有。请勿转载和采集!