模拟三个进程(生产者、消费者)

问题描述

模拟:父亲随机地剥橘子,削苹果,剥橘子要快些,削苹果要慢些,完成后放在盘子里,盘子只能容纳3颗水果。儿子只吃苹果,女儿吃橘子,儿子吃得快,女儿吃得慢。(假设他们都吃不饱)
使用信号量机制,并用三个进程模拟父亲、儿子、女儿的动作。

代码

i_semop.h

#ifndef I_SEMOP_H
#define I_SEMOP_H

#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>


#include<sys/types.h>//fundamental types of data
#include<sys/ipc.h>//interprocess communication
#include<sys/sem.h>//semaphore opration
#include<errno.h>
#include<fcntl.h>//file control

/*函数声明*/
/*信号量管理函数*/
int CreatSem(int value);
int SetSemValue(int sem_id, int value);
int DeleteSem(int sem_id);


/*P、V原语*/
int Psem(int sem_id);
int Vsem(int sem_id);
int rand_num();

#endif 

i_semop.c

#include"i_semop.h"


int SetSemValue(int sem_id, int value)
{

    if(semctl(sem_id, 0, SETVAL, value) == -1)
        return -1;

    return 1;
}


int CreatSem(int value)
{
    int sem_id;
    sem_id = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);
    if(-1 == sem_id)
        return -1;

    if(SetSemValue(sem_id, value) == -1)
        return -1;
    return sem_id;
}

int DeleteSem(int sem_id)
{
    if(semctl(sem_id, 0, IPC_RMID) == -1)
        return -1;

    return 1;
}

int Psem(int sem_id)
{
    struct sembuf semb;
    semb.sem_num = 0;   
    semb.sem_op = -1;
    semb.sem_flg = SEM_UNDO;

    if (-1 == semop(sem_id, &semb, 1))
        return -1;

    return 1;
}

int Vsem(int sem_id)
{
    struct sembuf semb;
    semb.sem_num = 0;   
    semb.sem_op = 1;
    semb.sem_flg = SEM_UNDO;

    if (-1 == semop(sem_id, &semb, 1))
        return -1;

    return 1;
}

int rand_num()
{   
    int ap_or_or = 3;

    /*获取一个随机数,0或者1, 表示随机的选苹果或者橘子*/
    srand(time(NULL));/*设置随机种子*/
    ap_or_or = rand() % 2;
    return ap_or_or;
}

main.c

#include"i_semop.h"
#include<signal.h>
#include<time.h>

#define APPLE 0
#define ORANGE 1

/*定义信号量为全局变量*/
int plate_sem = 0;
int apsem_in_plate = 0;
int orsem_in_plate = 0;

int main()
{
    /*信号量初始化*/
    plate_sem = CreatSem(3);
    if(-1 == plate_sem)
        fprintf(stderr, "creat plateSem failed\n");

    apsem_in_plate = CreatSem(0);
    if(-1 == plate_sem)
        fprintf(stderr, "creat apsem_in_plate failed\n");

    orsem_in_plate = CreatSem(0);
    if(-1 == plate_sem)
        fprintf(stderr, "creat orsem_in_plate failed\n");

    /*创建代表进程父亲,女儿,儿子*/
    pid_t pid_array[3];
    /*模拟动作*/
    pid_t pid = fork();
    if(0 == pid)//代表父亲
    {
        while(1)
        {
            int choice_apor = rand_num();//随机选择苹果或橘子
            //printf("随机数是%d\n",choice_apor);
            if(APPLE == choice_apor)//如果是削苹果皮
            {
                sleep(2);
                Psem(plate_sem);
                printf("父亲削了一个苹果\n");
                Vsem(apsem_in_plate);

            }
            else      //如果是剥橘子皮
            {
                sleep(1);
                Psem(plate_sem);
                printf("父亲剥了一个橘子\n");
                Vsem(orsem_in_plate);

            }
        }

    }
    else
        pid_array[0] = pid;

    pid = fork();   
    if(0 == pid)//代表儿子
    {
        while(1)
        {

            Psem(apsem_in_plate);
            printf("儿子吃了一个苹果\n");
            Vsem(plate_sem);

            sleep(1);
        }       

    }
    else
        pid_array[1] = pid;

    pid = fork();
    if(0 == pid) //代表女儿
    {
        while(1)
        {

            Psem(orsem_in_plate);
            printf("女儿吃了一个橘子\n");
            Vsem(plate_sem);

            sleep(2);
        }
    }
    else 
        pid_array[2] = pid;

    while(1)
    {
        char cmd = getchar();
        if('q' == cmd)
            break;
    }

    for(int i = 0; i < 3; i++)
        kill(pid_array[i], SIGTERM);

    DeleteSem(plate_sem);
    DeleteSem(apsem_in_plate);
    DeleteSem(orsem_in_plate);

    return 0;
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值