医生病人 信号量实验
Posted mumujzl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了医生病人 信号量实验相关的知识,希望对你有一定的参考价值。
操作系统课内实验 ——信号量
题目描述:
假设医院有 M(M >=1)个医生,每个医生的办公室很小,只能放一张桌子两个凳子,医生与病人一人坐一个,即一个医生一次只能给一位病人看病。当医生正在给某一位病人看病时,其他病人应该在办公室外走廊上的椅子上坐候,走廊上有 N(N>=3)个座位。当医生每看完一个病人,都会到走廊休息区看是否还有病人,若有病人等待看病则叫下一个病人进办公室为其看病,若没有病人等待,医生可以趴在桌子上休息;病人到达医生办公室,发现医生正在休息,必须立刻叫醒其中一位医生为其看病;如果病人到达医生办公室,发现所有医生正在为其 他病人看病,病人则坐在走其中一个椅子上等候;如果走廊上的座位已经坐满了,病人离开并选择一个随机时间返回医生办公室看病。
题目理解:
这是一个可以有多种做法的题目。简单点可以只设计患者进程,将医生的空闲数量作为信号量,在患者进程之间维护好信号量即可;也可以设计患者进程和医生进程,将空闲的椅子作为信号量
患者进程:
#include <stdio.h> #include <pthread.h> #include <semaphore.h> #include <unistd.h> #define maxn 100 const int doc_num=1; const int chair_num=3; const int pat_num=7; sem_t doc; sem_t chairs; pthread_t doctors[maxn]; pthread_t patients[maxn]; void *create_patient(void* arg){ /* 逻辑: 先询问医生空闲个数 若医生不空闲,则询问椅子个数 然后坐下开始等 */ int curr_doc_free=0; int curr_chair_free=0; int sleeptime; int id=*((int *)arg); //sem_getvalue(&doc,curr_doc_free); //printf("当前空闲医生个数:%d ",curr_doc_free); sem_getvalue(&chairs,&curr_chair_free); printf("当前空闲椅子个数:%d ",curr_chair_free); while(curr_chair_free==0) { printf("病人%d出去溜达了 ",id); //usleep(rand()%2000);//出去逛逛再回来 sleep(rand()%10); sem_getvalue(&chairs,&curr_chair_free); printf("当前空闲椅子个数:%d ",curr_chair_free); } sem_wait(&chairs); //等到了椅子 printf(" 病人%d坐下等候 ",id); sem_wait(&doc); sem_post(&chairs); printf(" 病人%d进入诊室接受治疗 ",id); //usleep(rand()%2000); sleep(rand()%7); printf(" 病人%d离开诊室 ",id); sem_post(&doc); } int main() { int ret; int i; int *id[maxn]; ret = sem_init(&doc,1,doc_num); if(ret==-1){ printf("init fail "); return 0; } ret = sem_init(&chairs,1,chair_num); if(ret==-1){ printf("init fail "); return 0; } /*for(int i=0;i<doc_num;i++){ ret=pthread_create(&doctors[i], NULL, work_doctor ); if(ret==-1) { printf("init fail "); return 0; } }*/ for(i=0;i<pat_num;i++){ id[i]=malloc(sizeof(int)); *id[i]=i; ret=pthread_create(&patients[i], NULL, create_patient,id[i]); if(ret==-1){ printf("init fail "); return 0; } else{ printf("病人%d准备看病(pthread_create) ",*id[i]); //usleep(rand()%2000); sleep(rand()%5); } } for(i = 0;i<pat_num;i++){ pthread_join(patients[i],NULL); } return 0; }
医生进程+患者进程:
//生产者消费者模型 #include <stdio.h> #include <pthread.h> #include <semaphore.h> #include <unistd.h> #define maxn 100 #define doc_num 2 #define chair_num 2 #define patient_num 7 sem_t doc; sem_t each_doct[doc_num];//1 free sem_t chairs; sem_t patients_camed; int camed=0; pthread_t doctors[maxn]; pthread_t patients[maxn]; void *create_doc(void* arg){//医生进程 int curr_chair_free=0; int flag1=0; int flag2=0; int id=*((int *)arg); int state; while(1){ sem_getvalue(&chairs,&curr_chair_free);//获取空椅子数量 sem_getvalue(&each_doct[id],&state);//获取医生是否被挂号 //sem_getvalue(&patients_camed,&camed); //printf("Camed%d ",camed); if(camed==patient_num){//所有病人均处理完毕 printf("医生%d下班啦 ",id); break; } printf("当前空闲椅子个数:%d ",curr_chair_free); //printf("当前医生%d状态:%d ",id,state); if(curr_chair_free==chair_num&&state==1){ flag1=1;//睡眠 flag2=0;//打印2 } if(curr_chair_free==chair_num&&flag1==1&&flag2==0&&state==1){ printf("晚安 医生%d开始睡觉了 ",id);//1 flag2=1;//打印2 } if (state==0){//轮到你啦~ if(flag1==1){ printf("医生%d醒了 ",id); flag1=0; } printf("医生%d开始接诊 ",id); sleep(rand()%5); sem_post(&each_doct[id]); sem_post(&doc); printf(" 病人离开诊室 ",id); sem_wait(&patients_camed); camed++; sem_post(&patients_camed); } sleep(1); } } void *create_patient(void* arg){//病人进程 /* 逻辑: 先询问医生空闲个数 若医生不空闲,则询问椅子个数 然后坐下开始等 */ int curr_doc_free=0; int curr_chair_free=0; int sleeptime; int id=*((int *)arg); int i,j; //sem_getvalue(&doc,curr_doc_free); //printf("当前空闲医生个数:%d ",curr_doc_free); sem_getvalue(&chairs,&curr_chair_free); //printf("当前空闲椅子个数:%d ",curr_chair_free); while(curr_chair_free==0){ printf("病人%d出去溜达了 ",id); sleep(rand()%3);//挂起 出去逛逛再回来 sem_getvalue(&chairs,&curr_chair_free);//查询空椅子个数 printf("当前空闲椅子个数:%d ",curr_chair_free); } sem_wait(&chairs); //等到了椅子 printf(" 病人%d坐下等候 ",id); sem_wait(&doc); //等到了医生 离座 sem_post(&chairs); for(i=0;i<doc_num;i++){ sem_getvalue(&each_doct[i],&j);//挂某个空闲医生的号 if(j==1){ sem_wait(&each_doct[i]); break; } } printf(" 病人%d进入诊室接受治疗 ",id); //usleep(rand()%2000); } int main() { int ret; int i; int *id_p[maxn]; int *id_d[maxn]; ret = sem_init(&doc,1,doc_num); if(ret==-1){ printf("init fail "); return 0; } ret = sem_init(&patients_camed,1,1); if(ret==-1){ printf("init fail "); return 0; } ret = sem_init(&chairs,1,chair_num); if(ret==-1){ printf("init fail "); return 0; } /*for(int i=0;i<doc_num;i++){ ret=pthread_create(&doctors[i], NULL, work_doctor ); if(ret==-1) { printf("init fail "); return 0; } }*/ for(i=0;i<doc_num;i++) { id_d[i]=malloc(sizeof(int)); *id_d[i]=i; ret = sem_init(&each_doct[i],1,1); ret=pthread_create(&doctors[i], NULL, create_doc,id_d[i]); if(ret==-1){ printf("init fail "); return 0; } } for(i=0;i<patient_num;i++) { id_p[i]=malloc(sizeof(int)); *id_p[i]=i; ret=pthread_create(&patients[i], NULL, create_patient,id_p[i]); if(ret==-1) { printf("init fail "); return 0; } else { printf("病人%d准备看病(pthread_create) ",*id_p[i]); //usleep(rand()%2000); sleep(rand()%2); } } for(i=0;i<doc_num;i++) pthread_join(doctors[i],NULL); for(i=0;i<patient_num;i++) pthread_join(patients[i],NULL); return 0; }
以上是关于医生病人 信号量实验的主要内容,如果未能解决你的问题,请参考以下文章