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

来源:互联网 发布:怎样开淘宝服装网店 编辑:程序博客网 时间:2024/05/09 11:11

问题描述

模拟:父亲随机地剥橘子,削苹果,剥橘子要快些,削苹果要慢些,完成后放在盘子里,盘子只能容纳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;}