爸爸给女儿和儿子喂水果。爸爸随机挑选橘子或者苹果,将橘子剥皮或者将苹果削皮放在盘子中,剥皮的速度比较快,而削皮的时间比较慢。女儿只吃橘子,儿子只吃苹果(当然我们假设女儿和儿子永远也吃不饱)。盘子只能装下3个水果。儿子吃得比较快,女儿吃得比较慢。
编程模拟该过程:
简单分析
信号量:
int accessplate = 1; //表示访问盘子的信号量
int apple = 0; //苹果个数
int orange = 0; //橘子
int emptyplates = 3; //空盘子
Father:
P(emptyplates);
produce a fruit
if( is apple )
then
P(accessplate)
put apple in
V(apple)
V(accessplate)
else
P(accessplate)
put orange in
V(orange)
V(accessplate)
Boy:
P(apple)
P(accessplate)
get an apple
eat an apple
V(emptyplates)
V(accessplate)
Girl:
P(orange)
P(accessplate)
get an orange
eat an orange
V(emptyplates)
V(accessplate)
代码:
#include <sys/mman.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <time.h> #include <sys/ipc.h> #include <sys/sem.h> /*overall varible*/ int numOfEmptyPlate_sem_id = 0; //number of empty plates. int numOfApple_sem_id = 0; //number of apple int numOfOrange_sem_id = 0; //number of orange int getAccesstoPlate = 0; //get plate int *plate = NULL; //3 PLATES struct sembuf P, V; // p,v opration void printPlates(const char *arg) { int i = 0; printf("%s\nFruits in plates:", arg); for(i=0; i<3; i++) { printf("%d ", plate[i]); } printf("\n"); } void father_do() // PUT FRUITS in {// 1 == apple, 2 == range int i = 0; semop( numOfEmptyPlate_sem_id, &P, 1); // P(empty plates) if( rand()%100+1 > 50) //get an orange { sleep(1); //get an orange,sleep 1 seconds semop( getAccesstoPlate, &P, 1); //P(plate) printf("Father get access to the plates.\n"); printPlates("father:"); for(i=0; i<3; i++) { if( 0 == plate[i]) //find an empty plate, and put the furit in { printf("%d ", plate[i]); plate[i] = 2; break; } } semop( numOfOrange_sem_id, &V, 1); //V(oranges) printf("Father put an orange in plate.\n"); semop( getAccesstoPlate, &V, 1); //V(plate) printf("Father put the plates back.\n"); } else // get an apple { sleep(2); //get an apple,sleep 2 seconds semop( getAccesstoPlate, &P, 1); //P(plate) printf("Father get access to the plates.\n"); printPlates("father:"); for(i=0; i<3; i++) { if( 0 == plate[i]) //find an empty plate, and put the furit in { printf("%d ", plate[i]); plate[i] = 1; break; } } semop( numOfApple_sem_id, &V, 1); //V(apples) printf("Father put an apple in plate.\n"); semop( getAccesstoPlate, &V, 1); //V(plate) printf("Father put the plates back.\n"); } } void girl_do() //EAT ORAGERS { int i = 0; semop( numOfOrange_sem_id, &P, 1); //P(oranges) sleep(2); //girl eat slowly,sleep 2 seconds semop( getAccesstoPlate, &P, 1); //P(plate) printf("Gilr get access to the plates.\n"); printPlates("girl:"); for( i=0; i<3; i++) { if( 2 == plate[i] ) { printf("%d ", plate[i]); plate[i] = 0; // eat an orange break; } } semop( numOfEmptyPlate_sem_id, &V, 1); // V(empty plates) printf("Girl eat an orange.\n"); semop( getAccesstoPlate, &V, 1); //V(plate) printf("Girl put the plates back.\n"); } void boy_do() // EAT APPLES { int i = 0; semop( numOfApple_sem_id, &P, 1); //P(apple) sleep(1); //boy eat fast,sleep 1 seconds semop( getAccesstoPlate, &P, 1); //P(plate) printf("Boy get access to the plates.\n"); printPlates("boy:"); for( i=0; i<3; i++) { if( 1 == plate[i] ) { printf("%d ", plate[i]); plate[i] = 0; // eat an apple break; } } semop( numOfEmptyPlate_sem_id, &V, 1); // V(empty plates) printf("Boy eat an apple.\n"); semop( getAccesstoPlate, &V, 1); //V(plate) printf("Boy put the plates back.\n"); } int main() { /*Process ID*/ pid_t father_id; pid_t girl_id; pid_t boy_id; char op =' '; srand( time(0)); // set rand seed plate=(int *)mmap(NULL, sizeof(int)*3, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS,-1,0); //GET SHARE MEMORY plate[0] = 0; plate[1] = 0; plate[2] = 0; //all plates are empty. numOfApple_sem_id = semget( IPC_PRIVATE, 1, IPC_CREAT|00666); numOfEmptyPlate_sem_id = semget( IPC_PRIVATE, 1, IPC_CREAT|00666); numOfOrange_sem_id = semget( IPC_PRIVATE, 1, IPC_CREAT|00666); getAccesstoPlate = semget( IPC_PRIVATE, 1, IPC_CREAT|00666); //Set signal measurement value(3 apples, 0 oranges) if( -1 == semctl(numOfApple_sem_id, 0, SETVAL, 0) || -1 == semctl(numOfEmptyPlate_sem_id, 0, SETVAL, 3) || -1 == semctl(numOfOrange_sem_id, 0, SETVAL, 0) || -1 == semctl(getAccesstoPlate, 0, SETVAL, 1) ) { perror("Semctl serval Error!\n"); } //init P,V opration V.sem_num = 0; V.sem_op = 1; V.sem_flg = SEM_UNDO; P.sem_num = 0; P.sem_op = -1; P.sem_flg = SEM_UNDO; father_id = fork(); if( father_id < 0 )//Error occures { fprintf(stderr, "Fork father Fail.\n"); } else if( 0 == father_id ) //father do { while(1) father_do(); } else { girl_id = fork(); if( girl_id <0 )//Error occures { fprintf(stderr, "Fork gril Fail.\n"); } else if( 0 == girl_id ) //girl do { while(1) girl_do(); } else { boy_id = fork(); if( boy_id < 0) //Error Occures { fprintf(stderr, "Fork boy Fail.\n"); } else if ( 0 == boy_id) //boy do { while(1) boy_do(); } else //main process { do{ op= getchar(); }while( op!='q'); exit(0); } } } return 0; }
运行截图:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)