操作系统作业3

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

一步一步来,一切就水到渠成了

#include<stdio.h>
#include<time.h> 
#include<stdlib.h>
struct fruit{
    int id;//0代表没水果,1代表桔子,2代表苹果 
    struct fruit *next;
}; 
int f=1,d=1,s=1;//三个是父亲女儿儿子的缩写,代表三个人是否被阻塞 
struct fruit *head=(struct fruit*)malloc(sizeof(struct fruit));

struct fruit *initfruit(){//初始化队列,5个结构体代表5个水果的状态 

    head->id=0; 
    struct fruit *p,*q;
    q=head;
    for(int i=0;i<4;i++){
        p=(struct fruit*)malloc(sizeof(struct fruit));
        q->next=p;
        p->id=0;//一开始盘子里的没水果,id全部为0 
        q=p; 
    }
    p->next=head;
    return head;
}
void putfruit(int i){//放水果操作 ,有空位则放水果,没有空位则阻塞爸爸 
    struct fruit *p;
    p=head;
    int flag=1,n=5,count=0;//flag用于限制只能进行放一个水果,n用于限制只能循环一遍 
    while(n--&&flag){//一共有5个节点,现在p指向第一个节点,所以遍历全部节点只需要4步,n取值<5保证不会进行多次无效循环 
        if(p->id==0){//这个节点没有放水果 
            if(i==1){
                p->id=1;
                printf("放入一个桔子\n");
                if(s==0){//如果儿子是属于阻塞态的,则唤醒儿子 
                    s=1;
                    printf("儿子被唤醒\n");
                } 
                flag=0; 
            }
            if(i==2){
                p->id=2;
                printf("放入一个苹果\n");
                if(d==0){//如果儿子是属于阻塞态的,则唤醒儿子 
                    d=1;
                    printf("女儿被唤醒\n");
                } 
                flag=0;
            }
        }
        else{
            count++;
            p=p->next;
        }
    }
    count++;//用来记盘子里水果数量 
    if(count==5){
        f=0;//如果p->next的id是0则代表p->next是head说明盘子已经满了,这时需要阻塞爸爸 
        printf("父亲被阻塞\n");
    } 
}
void searchfruit(int i){
    struct fruit *p;
    p=head;
    int flag=1,n=4;
    while(n--&&flag){
        if(i==1){
            if(p->id==1){
                flag=0;//一次只能吃一个水果 
                p->id=0; 
                printf("吃一个桔子\n");
            }
            else
                p=p->next; 
        }
        if(i==2){
            if(p->id==2){
                flag=0;
                p->id=0;
                printf("吃一个苹果\n");
            }
            else
                p=p->next; 
        }
    }
    if(flag==1){//判断是否吃过水果 
        if(i==1){
            s=0;
            printf("儿子被阻塞\n");
        }
        if(i==2){
            d=0;
            printf("女儿被阻塞\n");
        }
    }
    if(flag==0&&f==0){
        f=1;
        printf("唤醒爸爸\n");
    } 
}
void printfruit(){
    struct fruit *p;
    p=head;
    int n=5;

    printf("盘子现在的状态:|");
    while(n--){

        if(p->id==0){
            printf(" |");
        }
        else if(p->id==1){
            printf("O|");
        }
        else{
            printf("A|");
        }
        p=p->next; 
    }
    printf("\n");
} 
int main(){
    int n,flag=0,a,b;//a,b代表取随机数 
    printf("Please input scheduling count:");
    scanf("%d",&n);
    struct fruit *p,*pu;//*pu用于放入水果 
    p=initfruit();
    srand((unsigned)time(0));
    while(n--){//能抢资源的前提是没有被阻塞 
        a=rand()%3;//随机产生三个数字,0代表父亲抢到cpu资源,1代表儿子,2代表女儿
        b=rand()%2;//随机产生两个数用于确定是放桔子还是苹果,0代表桔子,1代表苹果
        if(a==0){//父亲抢到cpu资源,但是前提是还没有被阻塞 
            if(f==0){
                n++;//如果被阻塞那么后面代码不会执行,所以先n++,
                //用于消除后面continue(会运行n--)的影响 
                continue;
            }   
            if(b==0){//放桔子  
                printf("父亲抢到cpu资源\n");
                putfruit(1);
            }
            else{//放苹果 
                printf("父亲抢到cpu资源\n");
                putfruit(2);
            }
        }
        else if(a==1){//儿子抢到cpu资源
            if(s==0){
                n++;
                continue;
            }
            printf("儿子抢到cpu资源\n"); 
            searchfruit(1);//找桔子吃 

        }
        else if(a==2){//女儿抢到cpu资源 
            if(d==0){
                n++;
                continue;
            }
            printf("女儿抢到cpu资源\n");
            searchfruit(2); //找苹果吃 
        } 
        printfruit();//打印出此时盘子里水果的情况 
        printf("\n");
    }
    return 0;
}
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值