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

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等操作,比较繁琐,了解即可


http://www.kler.cn/news/336343.html

相关文章:

  • Docker系列-5种方案超详细讲解docker数据存储持久化(volume,bind mounts,NFS等)
  • Hive数仓操作(十六)
  • Flutter---适配高版本studio运行里面的Android项目报错
  • 网络层常用互联网协议
  • (15)衰落信道模型作用于信号是相乘还是卷积
  • Electron桌面应用打包现有的vue项目
  • 如何使用ssm实现基于Java的校园二手物品交易平台的设计与实现+vue
  • 【含开题报告+文档+PPT+源码】基于SpringBoot的校园互助平台设计与实现【包运行成功】
  • 多因素身份验证技术的原理及实现方式
  • node.js版本管理工具--nvm安装教程及配置(windows)
  • 【PostgreSQL】PG数据库表“膨胀”粗浅学习
  • UE4完整教程 UE4简介 UE4学习攻略及文件格式
  • ubuntu18.04 设置静态ip 00-installer-config.yaml
  • Leetcode - 140双周赛
  • 高轨SAR GESS系统1(CSDN_20241006)
  • 15分钟学 Python 第38天 :Python 爬虫入门(四)
  • AJAX 3——原理:XMLHttpRequest+Promise
  • 108页PPT丨OGSM战略规划框架:实现企业目标的系统化方法论
  • Redis入门第一步:认识Redis与快速安装配置
  • LeetCode 347.前 K 个高频元素