标签:malloc efi size wait 生产者消费者模型 打印 creat include thread
操作系统课内实验 ——信号量
题目描述:
假设医院有 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\n",curr_doc_free); sem_getvalue(&chairs,&curr_chair_free); printf("当前空闲椅子个数:%d\n",curr_chair_free); while(curr_chair_free==0) { printf("病人%d出去溜达了\n",id); //usleep(rand()%2000);//出去逛逛再回来 sleep(rand()%10); sem_getvalue(&chairs,&curr_chair_free); printf("当前空闲椅子个数:%d\n",curr_chair_free); } sem_wait(&chairs); //等到了椅子 printf(" 病人%d坐下等候\n",id); sem_wait(&doc); sem_post(&chairs); printf(" 病人%d进入诊室接受治疗\n",id); //usleep(rand()%2000); sleep(rand()%7); printf(" 病人%d离开诊室\n",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\n"); return 0; } ret = sem_init(&chairs,1,chair_num); if(ret==-1){ printf("init fail\n"); return 0; } /*for(int i=0;i<doc_num;i++){ ret=pthread_create(&doctors[i], NULL, work_doctor ); if(ret==-1) { printf("init fail\n"); 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\n"); return 0; } else{ printf("病人%d准备看病(pthread_create)\n",*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\n",camed); if(camed==patient_num){//所有病人均处理完毕 printf("医生%d下班啦\n",id); break; } printf("当前空闲椅子个数:%d\n",curr_chair_free); //printf("当前医生%d状态:%d\n",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开始睡觉了\n",id);//1 flag2=1;//打印2 } if (state==0){//轮到你啦~ if(flag1==1){ printf("医生%d醒了\n",id); flag1=0; } printf("医生%d开始接诊\n",id); sleep(rand()%5); sem_post(&each_doct[id]); sem_post(&doc); printf(" 病人离开诊室\n",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\n",curr_doc_free); sem_getvalue(&chairs,&curr_chair_free); //printf("当前空闲椅子个数:%d\n",curr_chair_free); while(curr_chair_free==0){ printf("病人%d出去溜达了\n",id); sleep(rand()%3);//挂起 出去逛逛再回来 sem_getvalue(&chairs,&curr_chair_free);//查询空椅子个数 printf("当前空闲椅子个数:%d\n",curr_chair_free); } sem_wait(&chairs); //等到了椅子 printf(" 病人%d坐下等候\n",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进入诊室接受治疗\n",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\n"); return 0; } ret = sem_init(&patients_camed,1,1); if(ret==-1){ printf("init fail\n"); return 0; } ret = sem_init(&chairs,1,chair_num); if(ret==-1){ printf("init fail\n"); return 0; } /*for(int i=0;i<doc_num;i++){ ret=pthread_create(&doctors[i], NULL, work_doctor ); if(ret==-1) { printf("init fail\n"); 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\n"); 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\n"); return 0; } else { printf("病人%d准备看病(pthread_create)\n",*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; }
标签:malloc efi size wait 生产者消费者模型 打印 creat include thread
原文地址:https://www.cnblogs.com/mumujzl/p/12179486.html