操作系统实验之猴子过桥问题的模拟程序

          操作系统实验之一,要求"参照生产者和消费者的程序,编写猴子过桥的模拟程序,要求避免死锁和饥饿"。

L:左边有猴子过桥

R:右边有猴子过桥

#include    <stdio.h>
#include    <stdlib.h>
#include    <unistd.h>
#include    <sys/ipc.h>
#include    <sys/shm.h>
#include    <sys/types.h>
#include    <sys/sem.h>
#include    "shmpc.h"
/*
 ********************************************************************************
 *         Name:  main
 *  Description:  entry point
 ********************************************************************************
 */

//var used to shared memory
int shmid;
void *myshm;
struct myshm_st *buf;

//var used to semaphore

int Lmutex,Rmutex,concur;
struct sembuf actionC;
struct sembuf actionA;
struct sembuf actionB;

//common var
int i,n;

void processA()
{
    //printf ( "Create a Producer Process Success,%d\n",getpid());
    printf ( "Create a LEFT monkey passing bridge Process Success,%d\n",getpid());

    //用来获取当前进程的进程识别码

    //attach share memory
    myshm=shmat(shmid,NULL,0);
    if(myshm==(void *)-1)
    {
        perror("shmat");
        exit(-1);
    }
    buf=(struct myshm_st *)myshm;

    //P concur ----------------------------
//        struct sembuf actionC;
    actionC.sem_num=0;
    actionC.sem_op=-1;
    actionC.sem_flg=SEM_UNDO;
    if(semop(concur,&actionC,1)==-1)
    {
        perror("semop");
        exit(0);
    }
    //-------------------------------------
    //P  Lmutex(A) ----------------------------
    actionA.sem_num=0;
    actionA.sem_op=-1;
    actionA.sem_flg=SEM_UNDO;
    if(semop(Lmutex,&actionA,1)==-1)
    {
        perror("semop");
        exit(0);
    }
    //-------------------------------------
    buf->m_rcount++;
    if(buf->m_rcount==1)
    {
        //P  Rmutex(B) ----------------------------

        actionB.sem_num=0;
        actionB.sem_op=-1;
        actionB.sem_flg=SEM_UNDO;
        if(semop(Rmutex,&actionB,1)==-1)
        {
            perror("semop");
            exit(0);
        }
        //-------------------------------------
    }
    //V Lmutex(A)---------------------------------------
    actionA.sem_op=1;
    if(semop(Lmutex,&actionA,1)==-1)
    {
        perror("semop");
        exit(0);
    }
    //--------------------------------
    //V concur---------------------------------------
    actionC.sem_op=1;
    if(semop(concur,&actionC,1)==-1)
    {
        perror("semop");
        exit(0);
    }

    //--------------------------------

    for(n=0; n<10; n++)
    {
        if(n==0)
        {
            while(buf->m_buf[0]=='L')
                sleep(1);
            buf->m_buf[0]='L';
        }
        sleep(1);
        bool flag=0;
        for(int j=0; j<10; j++)
            if(buf->m_buf[j]!='0')
                flag=1;
        if(flag)
        {

            bool ce=1;
            for(int j=0; j<10; j++)
            {
                if( buf->m_buf[j]=='R')
                    ce=0;
            }
            if(ce==0)break;

            printf("[%d/L/%d]:",getpid(),n);
            for(i=0; i<10; i++)
            {
                if(buf->m_buf[i]!='0')
                    printf("|%c",buf->m_buf[i]);
                else
                    printf("| ");
            }
            printf("|\n");
            //   if(buf->m_buf[9]!='R')
            for(int j=9; j>=0; j--)
            {
                buf->m_buf[j+1]=buf->m_buf[j];
                buf->m_buf[j]='0';
            }

        }
        else break;

    }




    //P  Lmutex(A) ----------------------------
    //  struct sembuf actionA;
    actionA.sem_num=0;
    actionA.sem_op=-1;
    actionA.sem_flg=SEM_UNDO;
    if(semop(Lmutex,&actionA,1)==-1)
    {
        perror("semop");
        exit(0);
    }
    //-------------------------------------


    buf->m_rcount--;
    if( buf->m_rcount==0)
    {
        //V Rmutex---------------------------------------

        actionB.sem_op=1;
        if(semop(Rmutex,&actionB,1)==-1)
        {
            perror("semop");
            exit(0);
        }
        //--------------------------------

    }
//V Lmutex(A)---------------------------------------
    actionA.sem_op=1;
    if(semop(Lmutex,&actionA,1)==-1)
    {
        perror("semop");
        exit(0);
    }
    //--------------------------------

    if(shmdt(myshm)==-1)
        perror("shmdt");
    exit(0);
}

void processB()
{

    printf ( "Create a RIGHT monkey passing bridge Process Success,%d\n",getpid());

    //attach share memory
    myshm=shmat(shmid,NULL,0);
    if(myshm==(void *)-1)
    {
        perror("shmat");
        exit(-1);
    }

    buf=(struct myshm_st *)myshm;

//P concur ----------------------------
    //     struct sembuf actionC;
    actionC.sem_num=0;
    actionC.sem_op=-1;
    actionC.sem_flg=SEM_UNDO;
    if(semop(concur,&actionC,1)==-1)
    {
        perror("semop");
        exit(0);
    }
    //-------------------------------------
//P  Rmutex(B) ----------------------------
//        struct sembuf actionB;
    actionB.sem_num=0;
    actionB.sem_op=-1;
    actionB.sem_flg=SEM_UNDO;
    if(semop(Rmutex,&actionB,1)==-1)
    {
        perror("semop");
        exit(0);
    }
    //-------------------------------------
    buf->m_lcount++;
    //        struct sembuf actionA;
    if(buf->m_lcount==1)
    {
        //P  Lmutex(A) ----------------------------
        actionA.sem_num=0;
        actionA.sem_op=-1;
        actionA.sem_flg=SEM_UNDO;
        if(semop(Lmutex,&actionA,1)==-1)
        {
            perror("semop");
            exit(0);
        }
        //-------------------------------------
    }

    //V Rmutex---------------------------------------
    actionB.sem_op=1;
    if(semop(Rmutex,&actionB,1)==-1)
    {
        perror("semop");
        exit(0);
    }
    //--------------------------------
    //V concur---------------------------------------
    actionC.sem_op=1;
    if(semop(concur,&actionC,1)==-1)
    {
        perror("semop");
        exit(0);
    }
    //--------------------------------

    for(n=0; n<10; n++)
    {
        bool sf=0;
        while(sf==0)
        {
            sf=1;
            for(int j=0; j<10; j++)
                if(buf->m_buf[j]=='L')
                {
                    sf=0;
                }
            if(sf==0)sleep(1);
        }
        if(n==0)
        {
            while(buf->m_buf[9]=='R')
                sleep(1);
            buf->m_buf[9]='R';
        }
        sleep(1);

        bool flag=0;
        for(int j=0; j<10; j++)
            if(buf->m_buf[j]!='0')
                flag=1;
        if(flag)
        {
            bool ce=1;
            for(int j=0; j<10; j++)
            {
                if( buf->m_buf[j]=='L')
                    ce=0;
            }
            if(ce==0)break;


            printf("[%d/R/%d]:",getpid(),n);
            for(i=0; i<10; i++)
            {
                if(buf->m_buf[i]!='0')
                    printf("|%c",buf->m_buf[i]);
                else
                    printf("| ");
            }
            printf("|\n");
            if(buf->m_buf[0]!='L')
                for(int j=1; j<10; j++)
                {
                    buf->m_buf[j-1]=buf->m_buf[j];
                    buf->m_buf[j]='0';
                }

        }
        else break;
        //  buf->m_rcount--;
    }

//P  Rmutex(B) ----------------------------
    //   struct sembuf actionB;
    actionB.sem_num=0;
    actionB.sem_op=-1;
    actionB.sem_flg=SEM_UNDO;
    if(semop(Rmutex,&actionB,1)==-1)
    {
        perror("semop");
        exit(0);
    }
    //-------------------------------------
    buf->m_lcount--;
    if(buf->m_lcount==0)
    {
//V Lmutex(A)---------------------------------------
        actionA.sem_op=1;
        if(semop(Lmutex,&actionA,1)==-1)
        {
            perror("semop");
            exit(0);
        }
        //--------------------------------
    }
    //V Rmutex---------------------------------------
    actionB.sem_op=1;
    if(semop(Rmutex,&actionB,1)==-1)
    {
        perror("semop");
        exit(0);
    }
    //--------------------------------


    if(shmdt(myshm)==-1)
        perror("shmdt");
    exit(0);

}

int main()
{
    char t;
    int ppid,cpid;

    //create a shared memery
    printf("Begin...\n");
    shmid=shmget(MYKEY,sizeof(struct myshm_st),IPC_CREAT|0770);
    //第一个参数是为共享内存段命名的,shmget()函数成功时返回一个与key相关的共享内存标识符
    //第三个参数是权限标志
    if( shmid==-1 )//如果调用失败,shmget调用失败返回-1
    {
        perror("shmget");//perror ( )用 来 将 上 一 个 函 数 发 生 错 误 的 原 因 输 出 到 标 准 设备
        exit(-1);
    }

    //attach shared memory
    myshm=shmat(shmid,NULL,0);
    //第一个参数是函数返回的共享内存的标志
    if(myshm==(void *)-1)
    {
        perror("shmat");
        exit(-1);
    }

    //init shared memory
    buf=(struct myshm_st *)myshm;
    buf->m_lcount=0;
    buf->m_rcount=0;
    for(int i=0; i<10; i++)
        buf->m_buf[i]='0';
    //create a semaphore信号量
    Lmutex=semget(MYKEY,1,IPC_CREAT|IPC_EXCL|0770);
    Rmutex=semget(MYKEYY,1,IPC_CREAT|IPC_EXCL|0770);
    concur=semget(MYKEYYY,1,IPC_CREAT|IPC_EXCL|0770);

    if( Lmutex==-1 )
    {
        perror("semget");
        exit(0);
    }
    if( Rmutex==-1 )
    {
        perror("semget");
        exit(0);
    }
    if(concur==-1 )
    {
        perror("semget");
        exit(0);
    }
    union semun init_val;
    init_val.val=1;
    if( semctl(Lmutex,0,SETVAL,init_val )==-1)//该函数用来直接控制信号量信息
    {
        perror("semctl");
        exit(0);
    }
    if( semctl(Rmutex,0,SETVAL,init_val )==-1)//该函数用来直接控制信号量信息
    {
        perror("semctl");
        exit(0);
    }
    if( semctl(concur,0,SETVAL,init_val )==-1)//该函数用来直接控制信号量信息
    {
        perror("semctl");
        exit(0);
    }
    for(;;)
    {

        scanf("%c",&t);
        char x=getchar();
        switch ( t )
        {
        case 'L' :
            //create a producer process
            ppid=fork();
            if( ppid==0 )
            {
                processA();
            }
            break;
        case 'R':
            cpid=fork();
            if( cpid==0 )
            {
                processB();
            }
            break;
        case 'q':
            if(shmdt(myshm)==-1)
                perror("shmdt");
            if(shmctl(shmid,IPC_RMID,0)==-1)
                perror("shmctl");
            if(semctl(Lmutex,1,IPC_RMID,NULL)==-1)
                perror("semctl");
            if(semctl(Rmutex,1,IPC_RMID,NULL)==-1)
                perror("semctl");
            if(semctl(concur,1,IPC_RMID,NULL)==-1)
                perror("semctl");
            exit(0);
            break;
        }
    }
    return 0;
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值