当前位置: 首页 > news >正文

信号量(信号灯) -----//目的:实现共享内存的多个进程之间同步

目录

一、信号量的分类

二、P/V操作

三、信号量相关函数 

1、创建或获取信号量 

2、实现p/v操作

3、设置信号量的信息


概念 
    信号量(集)(semaphore),也叫信号灯(集)。它是不同进程间或一个给定进程内部不同线程间同步的机制。

一、信号量的分类

    1》二值信号灯:
        值为0或1。与互斥锁类似,资源可用时值为1,不可用时值为0。

    2》计数信号灯:
      值在0到n之间。用来统计资代表源,其值可用资源数

二、P/V操作

    1》p操作 ---变红
       p操作也叫等待操作,是等待信号灯的值变为大于0,然后将其减1;
       
    2》V操作 ---变绿
        V操作也叫释放操作,用来唤醒等待资源的进程或者线程

三、信号量相关函数 

1、创建或获取信号量 

int semget(key_t key, int nsems, int semflg);
        //参数1 ----- key 
        //参数2 ----- 信号量集合中信号灯的个数
        //参数3 ----- 权限:信号灯集的访问权限,通常为IPC_CREAT | 0666
        //返回值 ---- 成功:信号量的ID,失败:-1
        
        例如: 

        int main(void)
        {
            key_t key;
            int sem_id;

            if((key = ftok("./",0xb)) < 0)
                perr("ftok");

            if((sem_id = semget(key,4,IPC_CREAT|0666)) < 0)
                perr("semget");

            return 0;
        }

  2、实现p/v操作 

int semop(int semid, struct sembuf *sops, size_t nsops);
         //参数1 ----- 信号量的ID 
         //参数2 ----- 结构体struct sembuf的指针 
        struct sembuf{
              unsigned short sem_num;  /* semaphore number 要操作的信号量的下标,从0开始 */
              short          sem_op;   /* semaphore operation 1-v操作 -1 --p操作,0 --等待,直到信号灯的值变成0 */
              short          sem_flg;  /* operation flags 一般为0,  IPC_NOWAIT,  SEM_UNDO */
        }
        //参数3 ----- 要操作的信号量的个数 
        //返回值----成功:0,失败:-1 
        
        //实现p操作

        void sem_p(int semid,unsigned short num,int nsops)
        {
            struct sembuf buf = {num,-1,0};
            if(semop(semid,&buf,nsops) < 0)
                perr("semop");
        }

        //实现V操作

        void sem_v(int semid,unsigned short num,int nsops)
        {
            struct sembuf buf = {num,1,0};
            if(semop(semid,&buf,nsops) < 0)
                perr("semop");
        }

   3、设置信号量的信息

 int semctl(int semid, int semnum, int cmd, ...);
         //参数1 ---- 信号量的ID 
         //参数2 ---- 要操作的信号量的编号
         //参数3 ---- 选项:
                        GETVAL:获取某个指定的信号灯的值
                        SETVAL:设置某个指定的信号灯的值
                        IPC_RMID:从系统中删除信号灯集合
                        SETALL: 设置所有的信号灯的值
        //变参 ----- 联合体: 
                         union semun {
                               int              val;    /* cmd为SETVAL,则使用val */
                               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
                               unsigned short  *array;  /* cmd为 GETALL, SETALL 则使用array*/
                               struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                                           (Linux-specific) */
                           };
        //返回值 ----成功:0,失败:-1
        
        例如:
        

        //给单个信号灯初始化
        void sem_init(int semid,int num,int value)
        {
            union semun un;
            un.val = value;
            if(semctl(semid,num,SETVAL,un) < 0)
                perr("semctl");
        }
        //给所有信号灯初始化
        void sem_init_all(int semid,int num,unsigned short *val_arr)
        {
            union semun un;
            un.array = val_arr;
            if(semctl(semid,num,SETVALL,un) < 0)
                perr("semctl");
        }

相关文章:

  • JS解决contenteditable=“true“的光标位置放到最后
  • 使用Qt的WebSocket模块小常识
  • 前端ES5,ES6模块Demo
  • 2022/08/31 吉软 JSP的基本使用
  • Nginx--Rewrite重写
  • vue——响应式数据、双向数据绑定、filter过滤器、面试题
  • MindMaster思维导图及亿图图示会员 超值获取途径
  • STD::pair<>的使用
  • 公众号搜题功能接口API
  • python3-python中的GUI,Tkinter的使用,抓取小米应用商店应用列表名称
  • 公众号查题接口API
  • 提高「程序员」的思维方式
  • EasyExcel自定义Converter解决LocalDateTime系列时间日期转换的问题
  • Nginx限流优化
  • 洗地机暗战:蓝海到血海,内卷的尽头没有赢家
  • SegmentFault for Android 3.0 发布
  • #Java异常处理
  • codis proxy处理流程
  • JavaScript设计模式系列一:工厂模式
  • java概述
  • Laravel5.4 Queues队列学习
  • LeetCode29.两数相除 JavaScript
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • SpringBoot 实战 (三) | 配置文件详解
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 技术胖1-4季视频复习— (看视频笔记)
  • 聚簇索引和非聚簇索引
  • 十年未变!安全,谁之责?(下)
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 一个JAVA程序员成长之路分享
  • 再次简单明了总结flex布局,一看就懂...
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​Java并发新构件之Exchanger
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (C)一些题4
  • (二)fiber的基本认识
  • (二)hibernate配置管理
  • (五)网络优化与超参数选择--九五小庞
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • .Net Remoting常用部署结构
  • .NET/C# 使用反射调用含 ref 或 out 参数的方法
  • /etc/fstab 只读无法修改的解决办法
  • /usr/bin/python: can't decompress data; zlib not available 的异常处理
  • /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)
  • []串口通信 零星笔记
  • [8-27]正则表达式、扩展表达式以及相关实战
  • [BUUCTF 2018]Online Tool(特详解)
  • [C#基础知识系列]专题十七:深入理解动态类型
  • [C/C++] -- 二叉树
  • [C++]高精度 bign (重载运算符版本)