用訊號量解決哲學家就餐問題
阿新 • • 發佈:2019-01-01
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #include <string.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) int semid; #define DELAY (rand() % 5 + 1 ) 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 sem_p(int semid) { struct sembuf sb = {0,-1,0}; int ret = semop(semid, &sb,1); if (ret == -1) ERR_EXIT("sem_p"); return ret; } int sem_v(int semid) { struct sembuf sb = {0,1,0}; int ret = semop(semid, &sb,1); if (ret == -1) ERR_EXIT("sem_p"); return ret; } void wait_for_2fork(int no) { int left = no; int right = (no+1)%5; struct sembuf sb[2] = { {left, -1, 0}, {right, -1, 0} }; semop(semid, sb, 2); } void free_2fork(int no) { int left = no; int right = (no+1)%5; struct sembuf sb[2] = { {left, 1, 0}, {right, 1, 0} }; semop(semid, sb, 2); } void philosophere(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(int argc, char *argv[]) { 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); } pid_t pid; int no; for (i = 0; i < 5; i++) { pid = fork(); if (pid == -1) ERR_EXIT("fork"); if (pid == 0) { no = i; break; } } philosophere(no); return 0; }