#include#include#include#include#include#include#include#include#include#include
#define DELAY (rand() % 5 + 1)
#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)*/};//semid ! this is the number of share memory
intsemid;//waiting for fork here//left and right = the number of sourses
void wait_for_1fork(intno)
{int left =no;//system defined struct//"first":the current number of pro//"second":resourses -1:wait cannot use;+1:can use//"thired":?
struct sembuf buf[1] ={
{left,-1, 0},
};//semop do wait or signal (p/v)//"first": the number of share memory pro//"second":the first point of struct//"third":the number of signal to complete
semop(semid, buf, 1);
}void wait_for_2fork(intno)
{int right = (no + 1) % 5;//system defined struct//"first":the current number of pro//"second":resourses -1:wait cannot use;+1:can use//"thired":?
struct sembuf buf[1] ={
{right,-1, 0}
};//semop do wait or signal (p/v)//"first": the number of share memory pro//"second":the first point of struct//"third":the number of signal to complete
semop(semid, buf, 1);
}void free_1fork(intno)
{int left =no;//system defined struct//"first":the current number of pro//"second":resourses -1:wait cannot use;+1:can use//"thired":?
struct sembuf buf[1] ={
{left,1, 0},
};
semop(semid, buf,1);
}void free_2fork(intno)
{int right = (no + 1) % 5;//system defined struct//"first":the current number of pro//"second":resourses -1:wait cannot use;+1:can use//"thired":?
struct sembuf buf[1] ={
{right,1, 0}
};
semop(semid, buf,1);
}void philosopere(intnum)
{
srand(getpid());for(; ;)
{//printf("%d is thinking\n", num);
printf("\033[36m%d is thinking\n\033[0m", num);if(num!=0)
sleep(DELAY);//printf("%d is hungry\n", num);
wait_for_1fork(num);//printf("%d pick up left chopsticks\n", num);
printf("\033[31m%d pick up left chopsticks\n\033[0m", num);
sleep(DELAY);
sleep(DELAY);
wait_for_2fork(num);//printf("%d pick up right chopsticks\n", num);
printf("\033[34m%d pick up right chopsticks\n\033[0m", num);//printf("%d is eating\n", num);
sleep(DELAY);
free_1fork(num);//printf("%d return left chopsticks\n", num);
printf("\033[33m%d return left chopsticks\n\033[0m", num);
sleep(DELAY);
free_2fork(num);//printf("%d return right chopsticks\n", num);
printf("\033[37m%d return right chopsticks\n\033[0m", num);
}
}intmain()
{//use IPC to connect between processes . A new share memory//semget() return the number of share memory//new signal key=0 and never change .So not use key//"first":use IPC_PRIVATE to share memory between relation processes//"second":(size_t)naxSize//"third":(int flag)private:666--read and write ; IPC_CREAT creat new memory
semid = semget(IPC_PRIVATE, 5, IPC_CREAT | 0666);if (semid == -1)
ERR_EXIT("semget");
union semun su;
su.val= 1;for (int i = 0; i < 5; i++)
{//creat a new object on "semid"//use i to depart 5 processes
semctl(semid, i, SETVAL, su);
}int no = 0;//pid_t (Process ID _ Type) Just like int
pid_t pid;for (int i = 1; i < 5; i++)
{//use fork() to make a copy of father process named with child pro//father.pid>0 and child.pid=0//after for loop will exist a father and five childs(0-4)
pid =fork();if (pid == -1)
ERR_EXIT("fork");if (pid == 0)
{
no=i;//break the child process loop to run the philosopere
break;
}
}
philosopere(no);return 0;
}