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

C++ Linux多进程同步-命名信号量

原文链接:C++ Linux多进程同步-命名信号量

匿名信号量一般是作为全局变量存在,用于线程通信,如果要实现进程通信需要定义命名变量.

进程同步

进程之间也可以使用信号量同步,信号量一般有两种库实现:POSIX信号量和C++20(<semaphore.h>) 以及 SystemV信号量(<sys/sem.h>传统的进程间同步机制)

标准库

<semaphore.h>

<semaphore.h>提供两种信号:POSIX和C++20
POSIX信号量更底层,支持进程和线程同步.而counting_semaphore本身只能支持线程同步,而且仅C++20适用

POSIX信号量

POSIX信号量是C标准库中的,兼容性更高

sem_t 本身就是一个信号量类型
sem_init(sem_t *sem, int pshared, unsigned int value): 初始化一个信号量。 pshared指明共享范围,不直接表示进程信号量,sem_wait(sem_t *sem): 等待信号量。
sem_post(sem_t *sem): 释放信号量。
sem_destroy(sem_t *sem): 销毁信号量。
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value); 创建命名信号量,命名信号量能够实现进程同步      value初始值 mode权限 oflag为标志,O_CREAT(打开,不存在则创建)O_EXCL(存在则报错)return SEM_FAILED失败 或 信号量指针
int sem_unlink(const char *name); 删除命名信号量
counting_semaphore信号量

c++20提供的counting_semaphore, binary_semaphore新的封装(binary_semaphore不如使用mutex实现或者使用counting_semaphore实现二值)

counting_semaphore(ptrdiff_t desired) :构造函数,传入初始信号值.
ptrdiff_t是两个指针差值范围,48字节(机器字长) 范围大于等于int,一般可以用int代替
void acquire() 占用
void release() 阻塞
bool try_acquire() 不阻塞占用,true 占用成功,false 占用失败
bool try_acquire_for(const std::chrono::duration<Rep, Period>& rel_time ) true 表示占用,false 为超出阻塞时间 这个感觉用处不大,过度封装了,实在需要可以自己实现  
ptrdiff_t max 计数上限
使用命名POSIX信号量实现父进程等待子进程输出
#include <iostream>
#include <semaphore.h>
#include <unistd.h>
#include <fcntl.h>
using namespace std;void child_process(sem_t* nsem){cout<<"child print"<<endl;sem_post(nsem);
}int main()
{sem_t* nsem=sem_open("name_sem",O_CREAT,0666,0);if (nsem == SEM_FAILED) {perror("sem_open");exit(EXIT_FAILURE);}pid_t cpid=fork();if(cpid==-1){perror("fork");exit(EXIT_FAILURE);}else if(cpid>0){sem_wait(nsem);cout<<"parent print"<<"\n";}else{sleep(0.005);child_process(nsem);}sem_destroy(nsem);sem_unlink("name_sem");return 0;
}

因此使用命名信号量就能实现所有进程之间的同步.只需要每个进程都打开该命名信号量即可

<sys/sem.h>

这个信号量库提供semget,semop,semctl等操作,比较繁琐,了解即可

相关文章:

  • HarmonyOS NEXT:实现电影列表功能展示界面
  • IDEA相关设置总结
  • 03Frenet与Cardesian坐标系(Frenet转Cardesian公式推导)
  • Win10 QT 配置Android开发环境-jdk/sdk/gradle
  • 探究Spring的单例设计模式--单例Bean
  • 25中国烟草校园招聘面试问题总结 烟草面试全流程及面试攻略
  • 国外电商系统开发-需求记录
  • 【C++】异常处理
  • Android Stuido中编译信息出现乱码的解决方式
  • ClickHouse | 查询
  • C++ | Leetcode C++题解之第446题等差数列划分II-子序列
  • 最大正方形 Python题解
  • 第二十三节:学习拦截器或者使用AOP实现用户token参数请求检测(自学Spring boot 3.x的第六天)
  • IDEA几大常用AI插件
  • springboot+satoken实现刷新token(值变化)
  • 深入了解以太坊
  • Angularjs之国际化
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • Electron入门介绍
  • If…else
  • iOS | NSProxy
  • jquery ajax学习笔记
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • k8s 面向应用开发者的基础命令
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • React Native移动开发实战-3-实现页面间的数据传递
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 给第三方使用接口的 URL 签名实现
  • 汉诺塔算法
  • 京东美团研发面经
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 深度学习在携程攻略社区的应用
  • 我与Jetbrains的这些年
  • 想写好前端,先练好内功
  • 用mpvue开发微信小程序
  • 阿里云ACE认证之理解CDN技术
  • 积累各种好的链接
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​​​​​​​STM32通过SPI硬件读写W25Q64
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • #{} 和 ${}区别
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (独孤九剑)--文件系统
  • (二)正点原子I.MX6ULL u-boot移植
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (一)kafka实战——kafka源码编译启动
  • (转)http协议
  • .FileZilla的使用和主动模式被动模式介绍
  • .NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .Net Memory Profiler的使用举例