设计要求:编程序模拟车站售票厅进程同步问题,售票厅任何时刻最多可容纳20名购票者进入,否则需要在外面等待。每个购票者可以看成一个进程。
售票厅任何时刻最多可容纳20名购票者进入,当售票大厅超过20人时,系统提示乘客需退出大厅等待;当大厅中人数少于或等于20人时,售票员开始售票,并提示等待的乘客进入大厅;
由于售票大厅是缓存区,最大容量为20,因此会出现3中情况:
① 若此时售票厅里人数为零时,则程序会提醒售票大厅为空,售票员的进程阻塞,直到购票者的进程运行完才唤醒该进程;
② 当进入售票厅内的人数还没有20时,进程将继续执行,则表示售票者的进程和购票者的进程都能执行;
③ 由于程序中的售票厅最大只能容纳20个人,所以,当售票厅内的人数进入将20时,则程序会提醒用户售票大厅的人数已满,请排队等候,购票者进程阻塞,直到售票者的进程运行完才唤醒该进程。
由于是多个购票者和多个售票者对应多个缓存区,因此,设置3个信号量:
同步信号量empty表示空缓存单元的个数,初值为20;
同步信号量full表示满缓冲单元的个数,初值为0;
互斥信号量mutex表示互斥使用的整个缓存池,初值为1;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 1、建立信号量 typedef int semaphore; typedef int item; item buffer[N] = {0};//缓存区 int in = 0;//进来缓存区的位置 int out = 0;//出去的缓存区的位置 int num=0;//此时缓存区的人数 int proCount = 0;// int purchaserNum,sellerNum;//售票者的人数,乘客的人数 semaphore mutex = 1, empty = N, full = 0, proCmutex = 1; //信号量的定义,empty=空的缓存区数量,full=满的缓存区的数量, proCmutex=1//生产乘客的信号量 typedef struct Node{ pthread_t temp; //进程 struct Node *next; //指针域 }Node,*LinkList;//定义链表 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 2、乘客进程 void * purchaser(void * a){ while(true){ while(proCmutex <= 0);//判断乘客是否产生 proCmutex--;//已产生 proCount++;//乘客的数量 while(empty <= 0){ printf("售票大厅已满!请排队等候\n"); }//P(empty),判断缓存区是否为满 while(mutex <= 0);//P(mutex),判断缓冲区是否被占用 mutex--;//将缓存区的状态变为正在被调用 if(buffer[in]==0) buffer[in] = proCount;//将进来的乘客序号放入缓冲区 in = (in + 1) % N;//进来的指针推进一位 full++; //V(full),表示满的缓存区增加 num++; //缓冲区的人数加一 printf("第%d乘客已进,此时售票大厅的人数为%d\n",proCount,num); empty--; //空的缓存区减少,乘客进来了缓存区 mutex++; //V(mutex),释放缓冲区 proCmutex++;//乘客已经进入售票大厅完,可再产生一名新的乘客 Sleep(sleepTime); pthread_exit(0);//进程结束 } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 3、售票员进程 void * seller(void *b){ while(true){ while(full <= 0){ printf("售票大厅为空!\n"); if(proCount==purchaserNum&&proCmutex==1)//判断售票员进程结束的标志:乘客全部离开售票大厅 exit(0);//进程结束 }//P(full),判断缓冲区是否为空 while(mutex <= 0);//P(mutex),判断缓冲区是否被占用 mutex--;//将缓存区的状态变为正在被调用 empty++;//V(empty),表示空的缓存区增加 int nextc = buffer[out];//找出离开位置的序号 buffer[out] = 0;//售票完将离开售票大厅,此时该位置为0 out = (out + 1) % N;//离开的指针加一 if(nextc!=0) { num--;//此时售票大厅的人数减一 full--;//表示满的缓冲区减少,乘客离开了缓存区 printf("\t\t\t\t第%d乘客已走,此时售票大厅的人数为%d\n", nextc,num); } mutex++;//V(mutex),释放缓冲区 Sleep(sleepTime); } } |