首页 > 系统相关 >linux 进程通信之信号量

linux 进程通信之信号量

时间:2024-05-05 21:56:16浏览次数:31  
标签:IPC semid int cmd 通信 信号量 linux sem

信号量 Linux函数semget();semctl();semop();

信号量三个函数

头文件#include<sys/sem.h>

int semget(key_t  _key ,int  _nsems,int _semflg);
int semctl(int _semid  ,int _semnum,int _cmd  ……);
int semop(int   semid ,struct    sembuf   *_sops ,size_t  _nsops);

semget

int semget(key_t  _key ,int  _nsems,int _semflg);
  • 功能:创建一个新的信号量或获取一个已经存在的信号量的键值。
  • 返回值:成功返回信号量的标识码ID。失败返回-1;

参数

  • _key:信号集的键值,注意是信号集,一个信号集会包含多个信号量,这个键值用来在多个进程中表示到同一个信号集,跟进程PID类似,如果系统已存在一个信号集的键值,那么申请到的就是同一个信号集
  • _nsems:这个信号集里面有多个信号量
  • _semflg:
    • IPC_CREAT如果信号量不存在,则创建一个信号量,否则获取。
    • IPC_EXCL只有信号量不存在的时候,新的信号量才建立,否则就产生错误。

示例

int semid=semget(8888,2,IPC_CREAT|0666);
//创建了一个键值为8888,权限为666的信号集,同时这个信号集包含了两个信号量

semctl

int semctl(int _semid  ,int _semnum,int _cmd  ……);
  • 功能:控制信号量的信息。
  • 返回值:成功返回0,失败返回-1;

参数

  • _semid:信号集的标志码(ID),也就是semget()函数的返回值;
  • _semnum:信号在信号集中的序号。从0开始排序
  • _cmd:
    • IPC_STAT读取一个信号量集的数据结构semid_ds,并将其存储在semun中的buf参数中。
    • IPC_SET设置信号量集的数据结构semid_ds中的元素ipc_perm,其值取自semun中的buf参数。
    • IPC_RMID将信号量集从内存中删除。
    • GETALL用于读取信号量集中的所有信号量的值。
    • GETNCNT返回正在等待资源的进程数目。
    • GETPID返回最后一个执行semop操作的进程的PID。
    • GETVAL返回信号量集中的一个单个的信号量的值。
    • GETZCNT返回这在等待完全空闲的资源的进程数目。
    • SETALL设置信号量集中的所有的信号量的值。
    • SETVAL设置信号量集中的一个单独的信号量的值。
  • Semunion:第4个参数是可选的,一般是union semun的实例
    这个联合体是需要自己定义的
      union semun {
          int   val;
          struct   semid_ds  *buf;
          unsigned short   *arrary;
      };
    
    _cmd为设置时,比如_cmd=SETALL,那么Semunion就是设置信号量的值
    _cmd为获取时,比如_cmd=GETALL,那么Semunion就是获取信号量的值

示例代码

如果要设置全部信号量的值

union semun {
        int   val;
        struct   semid_ds  *buf;
        unsigned short   *arrary;
    };

union semun  sem_args;
unsigned short array[3]={1, 2, 4}; //信号集里面信号量的值分别是: 1, 2, 4
sem_args.array = array;
ret = semctl(semid, 0, SETALL, sem_args);//当_cmd=SETALL时,第二个参数是什么都无所谓
if (-1 == ret){
    perror("semctl");
    exit(EXIT_FAILURE);
}

如果要获取全部信号量的值

union semun  sem_args;
unsigned short array[3];
sem_args.array = array;
ret = semctl(semid, 0, GETALL, sem_args);//当_cmd=GETALL时,第二个参数是什么都无所谓
if (-1 == ret){
    perror("semctl");
    exit(EXIT_FAILURE);
}
//array[]数值分别存储着各个信号量的值,当然是按顺序排好的

semop

int semop(int semid ,struct sembuf *_sops ,size_t _nsops);
  • 功能:用户改变信号量的值。也就是使用资源还是释放资源使用权。
  • 返回值:成功返回0,失败返回-1;

参数

  • semid:信号集的标志码(ID),也就是semget()函数的返回值;
  • _sops是一个指向结构体数组的指针。
struct sembuf{
    unsigned short sem_num;//第几个信号量,第一个信号量为0;
    short sem_op;//对该信号量的操作。
    short semflg;
};
  1. sem_op:
    1. sem_op=1:释放信号量,信号量的值+1
    2. sem_op=-1:等待一个信号量,信号量的值-1
      当信号量的值为0时,获取失败信号量失败
  2. _semflg:
    1. IPC_NOWAIT:等不到信号量不会阻塞(非阻塞式)
    2. IPC_UNDO:等不到信号量就阻塞(阻塞式等待)
  • nsops:操作结构的数量,恒大于或等于1

示例

struct sembuf sem_b;

sem_b.sem_num = 0;  //第0个信号量
sem_b.sem_op = 1;   //释放一个信号量,信号量的值+1
sem_b.sem_flg = SEM_UNDO; //不阻塞      当信号量的值为0时,获取信号量失败,阻塞
if(semop(semid, &sem_b, 1) == -1){
    fprintf(stderr, "error\n");
    return -1;
}

标签:IPC,semid,int,cmd,通信,信号量,linux,sem
From: https://www.cnblogs.com/mybbFHM/p/18173931

相关文章

  • linux lvm2卷 创建、备份与恢复
    自动快照snapper下载文档:https://documentation.suse.com/zh-cn/sles/12-SP5/html/SLES-all/cha-snapper.html查看存储信息有人吐槽btrfs不稳定,所以还是老办法吧:lvm2-ext4建议现在虚拟机内练习一下,再上实机。u盘用ventoy烧录(多系统支持),进入linux的iso镜像,打开控制台liveuse......
  • ADS安装教程(Linux)
    在linux服务器中,创建安装目录,这里选择的安装目录为/opt/ADSsudomkdir/opt/ADS解压安装包文件tar-xvfads......tarunzipPathWave.....zip运行安装命令sudo./SETUP.SH在安装过程中,需要输入安装目录,填选之前创建的目录/opt/ADS直接安装即可在软件使用过程中,licens......
  • Linux设置cp命令显示进度条
    1、前言实现原理:重新安装cp、mv命令,显示进度条测试环境:Centos7.6查看当前系统下的coreutils工具包的版本rpm-qa|grep-wcoreutils当前版本8.222、下载coreutils安装包不需要太新,8.32即可wgethttp://ftp.gnu.org/gnu/coreutils/coreutils-8.32.tar.xz3、下载补丁......
  • 信号量 semaphore的实现 -06
    1 semaphore的内核结构体注意:这是信号量,不是信号。在前面学习异步通知时,驱动程序给应用程序发信号。现在我们讲的信号量是一种同步、互斥机制。信号量的定义及操作函数都在Linux内核文件include\linux\semaphore.h中定义,如下: 初始化semaphore之后,就可以使用down函数或其他衍......
  • Linux 发行版选择
    简介要建立云服务器,首先需要安装操作系统。在现代环境中,几乎所有情况下都是指Linux操作系统。从历史上看,Windows服务器和其他类型的Unix在特定的商业环境中都很流行,但现在几乎每个人都在运行Linux,这是因为Linux支持广泛、许可免费或灵活,而且在服务器计算领域总体上无处不......
  • Matlab安装教程(Linux)
    解压安装包在虚拟机中,文件直接通过拖拽文件的方式将安装包拉入虚拟机时,文件通常存放在/tmp/VMwareDnD中,因此需要将存放文件位置的文件转移到/home/<用户名>/<存放目录>中参考命令如下:mv/tmp/VMwareDnD/<文件存放目录>/*/home/<用户名>/<存放目录>之后在存放压缩包的目录中,......
  • Linux基础
    目录一、Linux系统介绍二、Linux文件系统介绍三、什么是路径1、绝对路径2、相对路径3、特殊路径四、终端的使用技巧五、Linux系统命令1、常用的命令2、文件相关的命令3、目录相关的命令4、网络相关的命令5、其它命令六、通配符、管道、重定向1、通配符*代表任意多个字符?代表一......
  • Linux 下使用 NetLink 检测设备的热插拔
    一、简单介绍下NETLINK    netlink套接字是用以实现用户进程与内核(2.6.24之后的版本)进程通信的一种特殊的进程间通信(IPC),也是网络应用程序与内核通信的最常用的接口。二、为什么能用NETLINK检测设备热插拔    当我们的设备从主机上进行拔插时,内核会通过netlin......
  • Linux 输出重定向 2>&1 , 1>&2
    在shell程式中,最常使用的FD(filedescriptor)大概有三个,分别是:0是一个文件描述符,表示标准输入(stdin)1 是一个文件描述符,表示标准输出(stdout)2 是一个文件描述符,表示标准错误(stderr)在标准情况下,这些FD分别跟如下设备关联: stdin(0):keyboard键盘输入,并返回......
  • Linux 使用 inotify 监控文件或目录变化
    转载:https://www.cnblogs.com/PikapBai/p/14480881.html作者:PikapBai 1运行环境#操作系统:Ubuntu182inotify简介#inotify是一个Linux内核特性(监视文件系统事件),它用于监控文件系统,比如删除、读、写操作等,当发生对应事件时,则会触发inotify。当监控目录时,与该目录......