linux进程协作一个小例子

linux进程协作一个小例子,第1张

       爸爸给女儿和儿子喂水果。爸爸随机挑选橘子或者苹果,将橘子剥皮或者将苹果削皮放在盘子中,剥皮的速度比较快,而削皮的时间比较慢。女儿只吃橘子,儿子只吃苹果(当然我们假设女儿和儿子永远也吃不饱)。盘子只能装下3个水果。儿子吃得比较快,女儿吃得比较慢。

编程模拟该过程:

简单分析

信号量:

int accessplate = 1;     //表示访问盘子的信号量

int apple = 0;                    //苹果个数

int orange = 0;                  //橘子

int emptyplates = 3;          //空盘子

Father:

P(emptyplates);

produce a fruit

if( is apple )

then

         P(accessplate)

         put  apple in

         V(apple)

         V(accessplate)

else

         P(accessplate)

         put  orange in

         V(orange)

         V(accessplate)

Boy:

P(apple)

P(accessplate)

get an apple

eat an apple

V(emptyplates)

V(accessplate)

Girl:

P(orange)

P(accessplate)

get an orange

eat an orange

V(emptyplates)

V(accessplate)

代码:

#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/sem.h>
 
/*overall varible*/
int numOfEmptyPlate_sem_id = 0; //number of empty plates.
int numOfApple_sem_id = 0; //number of apple
int numOfOrange_sem_id = 0; //number of orange
int getAccesstoPlate = 0; //get plate
int *plate = NULL;         //3 PLATES
struct sembuf P, V;    // p,v opration
 
void printPlates(const char *arg)
{
    int i = 0;
    printf("%s\nFruits in plates:", arg);
    for(i=0; i<3; i++)
    {
        printf("%d ", plate[i]);
    }
    printf("\n");
}
 
void father_do()  // PUT FRUITS in
 
{// 1 == apple, 2 ==  range
    int i = 0;
    semop( numOfEmptyPlate_sem_id, &P, 1); // P(empty plates)
    if( rand()%100+1 > 50)  //get an orange
    {
        sleep(1);  //get an orange,sleep 1 seconds
        semop( getAccesstoPlate, &P, 1); //P(plate)
        printf("Father get access to the plates.\n");
        printPlates("father:");
        for(i=0; i<3; i++)
        {
            if( 0 == plate[i])  //find an empty plate, and put the furit in
            {
                printf("%d ", plate[i]);
                plate[i] = 2;
                break;
            }
        }
        semop( numOfOrange_sem_id, &V, 1); //V(oranges)
        printf("Father put an orange in plate.\n");
        semop( getAccesstoPlate, &V, 1); //V(plate)
        printf("Father put the plates back.\n");
    }
    else   // get an apple
    {
        sleep(2); //get an apple,sleep 2 seconds
        semop( getAccesstoPlate, &P, 1); //P(plate)
        printf("Father get access to the plates.\n");
        printPlates("father:");
        for(i=0; i<3; i++)
        {
            if( 0 == plate[i])  //find an empty plate, and put the furit in
            {
                printf("%d ", plate[i]);
                plate[i] = 1;
                break;
            }
        }
        semop( numOfApple_sem_id, &V, 1);  //V(apples)
        printf("Father put an apple in plate.\n");
        semop( getAccesstoPlate, &V, 1); //V(plate)
        printf("Father put the plates back.\n");
    }
}
 
void girl_do()    //EAT ORAGERS
{
    int i = 0;
    semop( numOfOrange_sem_id, &P, 1); //P(oranges)
    sleep(2); //girl eat slowly,sleep 2 seconds
    semop( getAccesstoPlate, &P, 1); //P(plate)
    printf("Gilr get access to the plates.\n");
    printPlates("girl:");
    for( i=0; i<3; i++)
    {
        if( 2 == plate[i] )
        {
            printf("%d ", plate[i]);
            plate[i] = 0; // eat an orange
            break;
        }
    }
    semop( numOfEmptyPlate_sem_id, &V, 1); // V(empty plates)
    printf("Girl eat an orange.\n");
    semop( getAccesstoPlate, &V, 1); //V(plate)
    printf("Girl put the plates back.\n");
}
 
void boy_do()   // EAT APPLES
{
    int i = 0;
    semop( numOfApple_sem_id, &P, 1); //P(apple)
    sleep(1); //boy eat fast,sleep 1 seconds
    semop( getAccesstoPlate, &P, 1); //P(plate)
    printf("Boy get access to the plates.\n");
    printPlates("boy:");
    for( i=0; i<3; i++)
    {
        if( 1 == plate[i] )
        {
            printf("%d ", plate[i]);
            plate[i] = 0; // eat an apple
            break;
        }
    }
    semop( numOfEmptyPlate_sem_id, &V, 1); // V(empty plates)
    printf("Boy eat an apple.\n");
    semop( getAccesstoPlate, &V, 1); //V(plate)
    printf("Boy put the plates back.\n");
}
 
int main()
{
    /*Process ID*/
    pid_t father_id;
    pid_t girl_id;
    pid_t boy_id;
    char op =' ';
 
    srand( time(0)); // set rand seed
    plate=(int *)mmap(NULL, sizeof(int)*3, PROT_READ|PROT_WRITE,
                      MAP_SHARED|MAP_ANONYMOUS,-1,0); //GET SHARE MEMORY
    plate[0] = 0;
    plate[1] = 0;
    plate[2] = 0;  //all plates are empty.
    numOfApple_sem_id = semget( IPC_PRIVATE, 1, IPC_CREAT|00666);
    numOfEmptyPlate_sem_id = semget( IPC_PRIVATE, 1, IPC_CREAT|00666);
    numOfOrange_sem_id = semget( IPC_PRIVATE, 1, IPC_CREAT|00666);
    getAccesstoPlate = semget( IPC_PRIVATE, 1, IPC_CREAT|00666);
 
    //Set signal measurement value(3 apples, 0 oranges)
    if( -1 == semctl(numOfApple_sem_id, 0, SETVAL, 0) ||
            -1 == semctl(numOfEmptyPlate_sem_id, 0, SETVAL, 3) ||
            -1 == semctl(numOfOrange_sem_id, 0, SETVAL, 0)  ||
        -1 == semctl(getAccesstoPlate, 0, SETVAL, 1) )
    {
        perror("Semctl serval Error!\n");
    }
    //init P,V opration
    V.sem_num = 0;
    V.sem_op = 1;
    V.sem_flg = SEM_UNDO;
    P.sem_num = 0;
    P.sem_op = -1;
    P.sem_flg = SEM_UNDO;
 
 
    father_id = fork();
    if( father_id < 0 )//Error occures
    {
        fprintf(stderr, "Fork father Fail.\n");
    }
    else if( 0 == father_id ) //father do
    {
        while(1)
        father_do();
    }
    else
    {
        girl_id = fork();
        if( girl_id <0 )//Error occures
        {
            fprintf(stderr, "Fork gril Fail.\n");
        }
        else if( 0 == girl_id ) //girl do
        {
            while(1)
            girl_do();
        }
        else
        {
            boy_id = fork();
            if( boy_id < 0) //Error Occures
            {
                fprintf(stderr, "Fork boy Fail.\n");
            }
            else if ( 0 == boy_id) //boy do
            {
                while(1)
                boy_do();
            }
            else  //main process
            {
                do{
                op= getchar();
                }while( op!='q');
                exit(0);
            }
        }
    }
    return 0;
}


运行截图:

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/2085824.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-07-22
下一篇 2022-07-22

发表评论

登录后才能评论

评论列表(0条)

保存