信号量 吃水果问题

信号量机制 实现 操作系统 吃水果问题 模拟程序

前言

参考代码
声名:主要根据这篇文章的思路,在其基础上增加了信号量机制。

题目

有一个盘子,可以放5个水果(苹果or桔子)。父亲每次向盘子随机放入一个水果(苹果 or桔子)父亲放入水果的次数不少于11次。儿子只吃桔子,女儿只吃苹果。请编程使用信号量机制模拟解决此进程同步问题。打印信息包括盘子的情况、调度的情况以及父亲、儿子或者女儿执行的操作。

题目解析

有题目可以得知父亲是生产者,儿子与女儿是消费者,其中,父亲随机在盘子中放入苹果和桔子,盘子满无法放入,当女儿和儿子那水果时,需要注意的是,两者只针对置于顶层的盘子所盛的水果是否是他们想要的,举例来说,现在第一个盘子里有苹果,第二个盘子里有桔子,而第一个盘子在顶层(即消费者指针指向第一个盘子)时,儿子去拿水果,会显示没有桔子,尽管桔子就在第二个盘子。

代码解释

  1. 定义消费者/生产者结构体存放父亲、女儿、儿子信息
  2. 定义盘子结构体
  3. 初始化消费者、生产者
  4. 将五个盘子初始化为循环链表
  5. 父亲用put指针操作盘子,儿子,女儿共用take指针操作盘子
  6. 同步信号量WAIT

代码实现

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <malloc.h>

#define PLATES 5

int WAIT[3] = {0, 0, 0};

struct Pcb{
    char name[20];
    int pid;
    int style;
    int fruit;
    char *act;
};

struct PcbList{
    struct Pcb item;
    struct Pcb * next;
};

struct Pan{
    char a[3];
    int frt;
    struct Pan * next;
};

struct PcbList * waitQueue;

void PanInit(struct Pan * head, int num){
        int i;
        struct Pan * np;
        struct Pan * lp;

        lp = head;
        for(i=0;i<num;++i){
                np = (struct Pan *)malloc(sizeof(struct Pan));
                np->a[0] = 'O';
                np->a[1] = 'A';
                np->a[2] = ' ';
                np->frt = 2;
                lp->next = np;
                np->next = NULL;
                lp = np;
        }
        np->next = head->next;
}

void Output(struct Pcb *p,struct Pan * head){
        int ps;
        struct Pan * temp = head ->next;
        printf("sched: %s \n",p->name);
        printf("%s\n",p->act);
        if(p->style == 0){
                printf("plate : |");
                for(ps=0;ps<PLATES;++ps){
                        printf("%c|",temp->a[temp->frt]);
                        temp = temp->next;
                }
                printf("\n");
        }
        printf("\n");
}

void wait(struct PcbList * head, struct Pcb * process){
    struct PcbList * temp = head;
    while(temp->next!=NULL){
        temp = temp->next;
    }
    int pid = (*process).pid;
    WAIT[pid] = 1;
    temp->next = process;
    temp = temp->next;
    temp->next = NULL;
    return;
};

struct Pcb * wakeUp(struct PcbList * head, struct Pcb * process){
    struct PcbList * temp = head;
    struct PcbList * pre = NULL;
    while(temp!=NULL){
        if(temp->item.pid == process->pid){
            int pid = (*process).pid;
            WAIT[pid] = 0;
            pre->next = temp->next;
            return &(temp->item);
        }else{
            pre = temp;
            temp = temp->next;
        }
    }
    return NULL;
};


struct Pcb *  PutFruit(struct Pan * put,struct Pcb * dad, struct Pcb * son, struct Pcb * dau){
        if(put->frt != 2){
                dad->act = "father: Pans is full, block me";
                wait(waitQueue, dad);
        }
        else{
                if(rand()%2==0){
                        put->frt = 0;
                        put = put->next;
                        dad->act = wakeUp(waitQueue, son) == NULL? "father: put an 'O'range": "father: put an 'O'range\nson wakeup";
                }
                else{
                        put->frt = 1;
                        put = put->next;
                        dad->act = wakeUp(waitQueue, dau) == NULL? "father: put an 'A'pple": "father: put an 'A'pple\ndau wakeup";
                }
        }
        return put;
}

struct Pcb * GetOrange(struct Pan * take,struct Pcb * son){
        if(take->frt == 0){
                take ->frt = 2;
                son->style = 0;
                take = take->next;
                son->act = "son: eat an orange";
        }
        else{
                son->act = "son: not orange, block me";
                wait(waitQueue, son);
        }
        return take;
}

struct Pcb * GetApple(struct Pan * take,struct Pcb * dau){
         if(take->frt == 1){
                take ->frt = 2;
                dau->style = 0;
                take = take->next;
                dau->act = "daughter: eat an apple";
        }
        else{
                dau->act = "daughter: not apple, block me";
                wait(waitQueue, dau);
        }
        return take;
}



int main()
{
    int num;
        int flag;
        struct Pcb Dad = {"father",0,0,0,NULL};
        struct Pcb Son = {"son", 1, 1, 0, NULL};
        struct Pcb Dau = {"daughter", 2, 1, 1, NULL};
        struct Pan *head;
        struct Pan *put;
        struct Pan *take;
        waitQueue = (struct PcbList *)malloc(sizeof(struct PcbList));
        waitQueue->next = NULL;


        head = (struct Pan *)malloc(sizeof(struct Pan));
        head->next = NULL;
        PanInit(head,5);
        put = head->next;
        take = head->next;
        printf("Please input scheduling count:");
        scanf("%d",&num);

        srand((unsigned) time(NULL));
        while(num--){
                flag = rand()%3;
                if(flag == 0 && WAIT[flag] == 0 ){
                        put = PutFruit(put,&Dad, &Son, &Dau);
                        Output(&Dad,head);
                }
                else if(flag == 1 && WAIT[flag] == 0){
                        take = GetOrange(take, &Son);
                        Output(&Son,head);
                        Son.style = 1;
                }
                else if(flag == 2 && WAIT[flag] == 0){
                        take = GetApple(take, &Dau);
                        Output(&Dau,head);
                        Son.style = 1;
                }else{
                    num++;
                    continue;
                }

        }

        return 0;
}

代码运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值