首页 > 代码库 > linux 环境下使用信号量实现司机售票员进程同步问题

linux 环境下使用信号量实现司机售票员进程同步问题

问题描述:

公共汽车上,司机和售票员的活动分别是:
司机的活动:启动车辆;正常行车;到站停车。
售票员的活动:关车门;售票;开车门。

在汽车不断的到站、停站、行驶过程中,用信号量和P,V操作实现它们的同步。

问题解决;

    我们可以使用两个信号量来实现司机与售票员间的同步,具体实现形式如下:

司机进程:

        司机开车;

        v(s2);

        p(s1);

        汽车离站;

 售票员进程:

    售票员售票;

    p(s2);

    售票员开车门;

    乘客上下车;

    售票员关车门;

    v(s1);

c代码实现:


#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/sem.h>
int semid1,semid2; //定义两个信号量
void v1(int semid1);
void v2(int semid2);
void p1(int semid1);
void p2(int semid2);
void conductor();
void driver();
//2.1定义semun共用体
union semun {
               int              val;
               struct semid_ds *buf;
               unsigned short  *array;
               struct seminfo  *__buf;

           };

int main()
{
        key_t key1,key2;定义信号量的key值
        //int semid1,semid2;
        //2.2定义信号量初始值
        union semun v1,v2;
        int r1,r2;
        //struct sembuf op1[1],op[2];
        //1.创建信号量
        key1=ftok(".",36);
        key2=ftok(".",98);
        if(key1==-1)
        {
                printf("key1 get erro:%m\n");
                exit(-1);
        }
        if(key2==-1)
        {
                printf("key2 get erro:%m\n");
                exit(-1);
        }
        //得到信号量
        semid1=semget(key1,1,IPC_CREAT|IPC_EXCL|0666);
        semid2=semget(key2,1,IPC_CREAT|IPC_EXCL|0666);
        //semid1=semget(key1,1,0);
        //semid2=semget(key2,1,0);
                if(semid1==-1)
                 {
                         printf("semid1 get erro:%m\n");
                         exit(-1);
                 }
                if(semid2==-1)
                 {
                         printf("semid2 get erro:%m\n");
                         exit(-1);
                 }

        //printf("semid1:%d\n",semid1);
        //printf("semid2:%d\n",semid2);
        //2.初始化信号量为0
        v1.val=0;
        v2.val=0;
                r1=semctl(semid1,0,SETVAL,v1);
                r2=semctl(semid2,0,SETVAL,v2);
                if(r1==-1)
                 {
                         printf("r1 get erro:%m\n");
                         exit(-1);
                 }
                if(r2==-1)
                 {
                        printf("r2 get erro:%m\n");
                         exit(-1);
                 }
        if(fork()>0)            //父进程
        {
                driver();
        }
        else                    //子进程
        {
                conductor();
        }

        //4.删除信号量
        semctl(semid1,0,IPC_RMID);
        semctl(semid2,0,IPC_RMID);

return 0;
}

void p1(int semid1)
{
        struct sembuf op1[1];
        op1[0].sem_num=0;
        op1[0].sem_op=-1;//p进行-1操作
        op1[0].sem_flg=0;
        semop(semid1,op1,1);
}
void p2(int semid2)
{
        struct sembuf op2[1];
        op2[0].sem_num=0;
        op2[0].sem_op=-1;//p进行-1操作
        op2[0].sem_flg=0;

         semop(semid2,op2,1);
}
void v1(int semid1)
{
        struct sembuf op1[1];
        op1[0].sem_num=0;
        op1[0].sem_op=1;//v进行+1操作
        op1[0].sem_flg=0;

        semop(semid1,op1,1);
}
void v2(int semid2)
{
        struct sembuf op2[1];
        op2[0].sem_num=0;
        op2[0].sem_op=1;//v进行+1操作
        op2[0].sem_flg=0;

        semop(semid2,op2,1);
}
void driver()//司机操作函数
{
        while(1)
        {
        printf("driver开车\n");
        v2(semid2);
        p1(semid1);
        printf("driver离站\n");
        sleep(1);
        }

}
void conductor()//售票员操作函数
{
        while(1)
       {
        printf("conductor售票\n");
        p2(semid2);
        printf("conductor开车门\n");
        printf("passenger上下车\n");
        printf("conductor关车门\n");
        v1(semid1);
        sleep(1);
        }
}

linux 环境下使用信号量实现司机售票员进程同步问题