操作系统作业03

操作系统作业——进程互斥同步的模拟

题目

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

题目解析

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

代码解释

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

代码实现

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

#define PLATES 5
struct Pcb{             //储存父亲,儿子,女儿信息的结构体
        char name[20];     //名称
        int Pid;        //消费者/生产者id
        int style;      //决定工作方式,消费者还是生产者
        int fruit;      //决定生产或者消费何种水果
        char *act;
};

struct Pan{             //盘子结构体
        char a[3];          //字符数组分别代表桔子和苹果
        int frt;
        struct Pan * next;              //指针

};

/*初始化盘子列表*/
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);                  //输出操作人员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");
}

/*父亲放水果操作*/
struct Pcb *  PutFruit(struct Pan * put,struct Pcb * dad){
        if(put->frt != 2){
                //盘子满了
                dad->act = "father: Pans is full";
        }
        else{
                if(rand()%2==0){
                        put->frt = 0;            //放水果操作
                        put = put->next;
                        dad->act = "father: put an 'O'range";
                }
                else{
                        put->frt = 1;           //放苹果
                        put = put->next;        //生产者指针后移
                        dad->act = "father: put an 'A'pple";
                }
        }
        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";
        }
        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";
        }
        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;


        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){
                        put = PutFruit(put,&Dad);               //生产者操作
                        Output(&Dad,head);                       //输出
                }
                else if(flag == 1){
                        take = GetOrange(take, &Son);      //消费者操作
                        Output(&Son,head);                       //输出
                        Son.style = 1;                         //是否消费标记位重置
                }
                else if(flag == 2){
                        take = GetApple(take, &Dau);
                        Output(&Dau,head);
                        Son.style = 1;
                }

        }

        return 0;
}

代码运行结果

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值