医生病人 信号量实验

Posted mumujzl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了医生病人 信号量实验相关的知识,希望对你有一定的参考价值。

操作系统课内实验 ——信号量

  题目描述:

  假设医院有 MM >=1)个医生,每个医生的办公室很小,只能放一张桌子两个凳子,医生与病人一人坐一个,即一个医生一次只能给一位病人看病。当医生正在给某一位病人看病时,其他病人应该在办公室外走廊上的椅子上坐候,走廊上有 NN>=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;
}

 

 

 

 

 

 

  

以上是关于医生病人 信号量实验的主要内容,如果未能解决你的问题,请参考以下文章

实验一:医院住院管理系统需求|软件工程

实验二:数据流图建模实验|软件工程

实验二:数据流图建模实验|软件工程

实验二:数据流图建模实验|软件工程

软件工程导论 习题二

hdu 1873 看病要排队(优先级队列)