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);
        }
}

时间: 2024-10-13 09:11:22

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

Linux环境下线程消息同步的陷阱

我们程序中常常会使用到线程间的消息同步处理,比如以下一段伪码 var message = "": void func()  {   1. 启动线程Thread(该线程中填充message的内容):   2. 阻塞,直到等待到完成message填充的事件:   3. 处理message:   .... } void Thread()  {   1. 通过某种处理填充message:   2. 触发func中的阻塞事件: } 我们通常会使用条件变量来完成类似情况的线程同步处理 比如wind

mosquitto在Linux环境下的部署/安装/使用/测试

mosquitto在Linux环境下的部署 看了有三四天的的源码,(当然没怎么好好看了),突然发现对mosquitto的源码有了一点点感觉,于是在第五天决定在Linux环境下部署mosquitto. 使用传统源码安装步骤: 步骤1:http://mosquitto.org/files/source/官网下载源码,放到Linux环境中.解压后,找到主要配置文件config.mk,其中包含mosquitto的安装选项,需要注意的是,默认情况下mosquitto的安装需要OpenSSL(一个强大的安全

多线程编程之Linux环境下的多线程(二)

上一篇文章中主要讲解了Linux环境下多线程的基本概念和特性,本文将说明Linux环境下多线程的同步方式. 在<UNIX环境高级编程>第二版的“第11章 线程”中,提到了三种基本的同步机制:互斥.读写锁.条件变量.下面分别针对这三种机制进行说明: 一.线程互斥 互斥意味着具有“排它性”,即两个线程不能同时进入被互斥保护的代码.Linux下可以通过pthread_mutex_t 定义互斥体机制完成多线程的互斥操作,该机制的作用是对某个需要互斥的部分,在进入时先得到互斥体,如果没有得到互斥体,表明

多线程编程之Linux环境下的多线程(三)

前面两篇文章都讲述了Linux环境下的多线程编程基础知识,也附带了典型实例.本文主要比较一下Linux环境与Windows环境下的多线程编程区别. 看待技术问题要瞄准其本质,不管是WIN32.Linux还是VxWorks,其涉及到多线程的部分都是那些内容,无非就是线程控制和线程通信,它们的许多函数只是名称不同,其实质含义是等价的,下面我们来列个三大操作系统共同点详细表单: 事项 WIN32 Linux VxWorks 线程创建 CreateThread pthread_create taskSp

(1)Jenkins Linux环境下的简单搭建

(1)Jenkins Linux环境下的简单搭建 Jenkins是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. ----百度百科 这是一款基于Java开发的工具.种种原因,最近刚开始接触,决定研究一下.Jenkins的搭建方法不止一种,一下就是个人总结的其中一种,文章内容比较浅显,不足之处,欢迎指正. 首先,所需要准备的工具JDK.Maven.资料上显示JDK版本最好高于1.7,并没有研究1.7以下版本,所谓"没有实际调研,就没有发言权",在此就不做过多

ant+jmeter 在Linux环境下接口自动化测试环境搭建(2)

上一篇讲过在Windows下搭建的方法,今天这里写一下在Linux环境下搭建的方法. 实验准备:Linux服务器一台. 服务器上安装好jdk,配置好环境变量. 服务器上配置好ant. 工具准备: Jdk下载地址: http://www.oracle.com/technetwork/java/javase/downloads/index.html Jmeter下载地址 http://jmeter.apache.org/ Ant下载地址 http://ant.apache.org/ 环境准备: 所以

Linux环境下线程的同步与互斥以及死锁问题

由于本次要讨论操作系统的死锁问题,所以必须先研究的是linux环境下的线程同步与互斥 先看下面的代码 大家猜想输出应该是什么呢? 结果是下面这个样子 好吧,似乎并没有什么区别... 那么下面再看这段代码(请无视并忽略屏蔽的内容...) 大家猜想正确的结果是什么呢?5000,10000? 好吧,或许你们都错了. 在运行了一段时间后,它的结果是这样的. 是不是又对又错? 为什么呢? 这就是因为程序中printf语句作用:本身是库函数,所以必须进行系统调用,必须进入内核进行切换,有很大概率形成数据的混

Linux环境下使用JFS文件系统

Linux环境下使用JFS文件系统 JFS是IBM公司为linux系统开发的一个日志文件系统.从IBM的实力及它对Linux的态度来看,JFS应该是未来日志文件系统中最具实力的一个文件系统. JFS提供了基于日志的字节级文件系统,该文件系统是为面向事务的高性能系统而开发的.JFS 能够在几秒或几 分钟内就把文件系统恢复到一致状态.JFS能够保证数据在任何意外宕机的情况下,不会造成磁盘数据的丢失与损坏. 一.JFS文件系统特点 1.存储空间更大 JFS 支持的最小文件系统是 16M 字节.最大文件

Linux环境下安装Tigase XMPP Server

Tigase是一种XMPP服务器,可以作为采用XMPP协议的各种IM(Instant Messeging)工具(如Pandion.Spark等)的服务器. 在Linux环境下安装Tigase的步骤如下: (1)下载安装文件 到https://projects.tigase.org/projects/tigase-server/files下载安装文件,我下载的是tigase-server-5.2.0-b3447-dist.tar.gz. (2)解压缩 创建一个文件夹,将tigase-server-