美文网首页
Linux IPC之信号量

Linux IPC之信号量

作者: 温柔倾怀 | 来源:发表于2021-01-26 20:48 被阅读0次

创建一个信号量

//创建之后一直存在,除非主动删除
int sem_id;
//semget第二个参数为信号量集(数组)中信号量的个数
sem_id = semget(1000,1,IPC_CREAT|0600);
ERROR_CHECK(sem_id,-1,"semget");

将信号量初始化|设置信号量的值

//semctl函数
//第二个参数为信号量在信号量集(数组)中的下标
//初始化时,第三个参数为 SETVAL
//第四个参数为初始化的值
int ret = semctl(sem_id,0,SETVAL,1);
//成功返回0
ERROR_CHECK(ret,-1,"semctl");

获取信号量的值

ret = semctl(sem_id,0,GETVAL);
ERROR_CHECK(ret,-1,"semctl");

实现PV操作

//P定义一个结构体
//V定义一个结构体
struct sembuf sopp,sopv;
//P操作
sopp.sem_num = 0;
sopp.sem_op = -1;
sopp.sem_flag = SEM_UNDO;
//V操作
sopv.sem_num = 0;
sopv.sem_op = 1;
sopv.sem_flag = SEM_UNDO;

if(!fork())
{
    for(int i=0;i<100000000;i++)
    {
        //加锁
        semop(sem_id,&sopp,1);
        p_start[0] = p_start[0]+1;
        //解锁
        semop(sem_id,&sopv,1);
    }
}

参数cmd为执行的操作

  • IPC_RMID 立即删除信号量,唤醒所有被阻塞的进程
  • GETVAL 返回信号量的值,从0开始,第一个信号量编号为0
  • SETVAL 设定信号量的值,从0开始,第一个信号量编号为0

删除信号量集合

//删除信号量集合
ret = semctl(sem_id,0,IPC_RMID);
ERROR_CHECK(ret,-1,"semctl");

批量设置多个信号量的值

unsigned short arrays[2]={0,10};
int ret = semctl(sem_id,0,SETALL,arrays);

生产者消费者

#include <func.h>

int main(int argc,char*argv[])
{
    int sem_id;
    //两个信号量
    sem_id = semget(1000,2,IPC_CREAT|0600);
    ERROR_CHECK(sem_id,-1,"semctl");
    //生产者消费者 计数信号量
    //0号信号量代表产品数目
    //1号信号量代表仓库数目
    unsigned short arrays[2]={0,10};
    int ret;
    //对两个信号量同时进行初始化
    ret = semctl(sem_id,0,SETALL,arrays);
    ERROR_CHECK(ret,-1,"semctl");
    //将arrays都设置为0
    //memset(arrays,0,sizeof(arrays));
    //子进程是出库进程,消费者
    //父进程是入库进程,生产者
    if(!fork()){
        //出库,产品-,仓库空间+,故0号信号量p操作,1号信号量v操作
        struct sembuf sopp0,sopv1;
        sopp0.sem_num=0;
        sopp0.sem_op=-1;
        sopp0.sem_flg=SEM_UNDO;
        sopv1.sem_num=1;
        sopv1.sem_op=1;
        sopv1.sem_flg=SEM_UNDO;
        while(1){
        //子进程出库
        printf("I am Customer,product num = %d space num = %d \n",semctl(sem_id,0,GETVAL),semctl(sem_id,1,GETVAL));
        //对产品-1 P操作
        semop(sem_id,&sopp0,1);
        printf("start out...\n");
        //对仓库个数+1
        semop(sem_id,&sopv1,1);
        printf("I am Customer,product num = %d space num = %d \n",semctl(sem_id,0,GETVAL),semctl(sem_id,1,GETVAL));
        sleep(2);
        } 
    }else{
        //入库
        //产品+,仓库空间-, 0号信号量+1,1号信号量-1
        struct sembuf sopp1,sopv0;
        sopv0.sem_num=0;//在信号量集合中的编号
        sopv0.sem_op=1;//V操作 +1
        sopv0.sem_flg=SEM_UNDO;
        sopp1.sem_num=1;
        sopp1.sem_op=-1;
        sopp1.sem_flg=SEM_UNDO;
        while(1)
        {
            printf("I am Productor,product num = %d space num = %d\n",semctl(sem_id,0,GETVAL),semctl(sem_id,1,GETVAL));
            //对仓库数-1,先要有位置了才能放入
            semop(sem_id,&sopp1,1);
            printf("start in...\n");
            //产品数+1
            semop(sem_id,&sopv0,1);
            printf("I am Productor,product num = %d space num = %d\n",semctl(sem_id,0,GETVAL),semctl(sem_id,1,GETVAL));
            sleep(1);
        }
    } 
    return 0;
}

SEM_UNDO

设置为SEM_UNDO,当杀掉一个进程的时候,这个进程对该某信号的操作会较初始值全部反向操作回去.(若P操作减了三十次,则较初始值加回三十)

若要减三十多次,不能减为负值,那就为0

PV的非计数信号量,需要用SEM_UNDO.

相关文章

  • 第2章 IPC机制

    2.1 Android IPC简介 Linux的IPC通信机制:命名通道、共享内存、信号量等来进行IPC。 And...

  • Android binder解析

    Linux 系统提供的进程间通信(IPC)方式 Signals 信号量(System V IPC) Pipes 管...

  • 《Android开发艺术探索》第二章----IPC机制

    Android开发艺术探索 第二章IPC机制 Linux中IPC通信方式?答:命名管道,共享内存,信号量(具体再细...

  • IPC机制

    2.1 Android IPC机制任何一个操作系统都需要IPC机制,Linux可以通过共享内存,管道,信号量来进行...

  • Linux IPC之信号量

    创建一个信号量 将信号量初始化|设置信号量的值 获取信号量的值 实现PV操作 参数cmd为执行的操作 IPC_RM...

  • 多线程同步之 POSIX 同步

    信号量 Linux 下有信号量的API有两个,一个是之前讲的System V IPC信号量,现在讨论的是POSIX...

  • Android跨进程通信IPC系列

    Android跨进程通信IPC之1——Linux基础Android跨进程通信IPC之2——Linux的跨进程通信详...

  • DBus for IPC in Qt

    Linux 系统IPC种类: 信号 管道 命名管道 信号量 消息队列 共享内存 内存映射文件 套接字 DBus 概...

  • 春招笔记

    Linux支持的IPC:管道,消息队列,共享内存,信号量,Socket。只有Socket支持CS模式,其他的也可以...

  • Android Framework中关于Binder的浅认识

    Android Binder 简单认识 虽然Linux提供了上述(还有其它的如信号量等)的IPC方式,但是由于每种...

网友评论

      本文标题:Linux IPC之信号量

      本文链接:https://www.haomeiwen.com/subject/yosnzktx.html