进程间通信--信号量

本文深入探讨了信号量的概念,包括二元信号、计数信号量和计数信号量集,详细解释了信号量数据结构及其各部分作用。同时介绍了信号量的创建、操作方法及控制命令,如semget、semop、semctl等,帮助读者理解如何在进程间实现同步和互斥。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

信号量不是IPC机构,它只是一个计数器用于不同进程之间或同一进程不同线程之间的同步,类型:二元信号:值为011说明有可用资源,0说明此时资源占用,其他进程需等待。计数信号量:表示可用资源数量。计数信号量集:由一个或多个信号量组成的集合,每一个都是计数信号量。

信号量数据结构:

#include <sys/sem.h>
struct semid_ds                                // 信号量描述符{
      struct ipc_perm        sem_perm;        // 操作权限结构体
      struct sem *   sem_base;        // 信号量指针
      ushort  sem_nsems;        // 信号量数量
      time_t  sem_otime;        // 最近一次操作的时间
      time_t  sem_ctime;        // 上一次修改时间
 };
 #include <sys/ipc.h>
 struct ipc_perm                                //权限设置结构体 
{
            uid_t        uid;                            // 所有者用户ID
            gid_t        gid;                            // 所有者组ID
            uid_t        cuid;                            // 创建者ID
            gid_t        cgid;                            // 创建者组ID
            mode_t    mode;                            // 读写权限
            ulong_t    seq;                            // 槽的使用序列号
            key_t        key;                            // IPC键
};  
  struct sem	{
            ushort_t        semval;                        // 信号值,非负
            short            sempid;                        // 上一次对其进行成功操作的进程PID
            ushort_t        semncnt;                        // 等待semval增加(长)的进程数
            ushort_t        semzcnt;                        // 等待semval=0(为0)的进程数    
 }

信号的创建和操作:

#include<sys/types.h>

#incldue<sys/ipc.h>

#include<sys/sem.h>

int semget (key_t key , int nsems , int flag) 

获取一个信号量集,key是一个键值由ftok获得,nsems:信号量集合中信号个数,flag读写标志位。

int semop(int semid , struct sembuf *opsptr , size_t nops) 

对创建好的信号量集操作,参数struct sembuf {

short sem_num; //信号编号

short sem_op;  //信号操作

short sem_flag;  //信号标志

}

opsptr指向数组的每一个sembuf表示一个特定信号量的操作,nops标志指向数组大小。

sem_op为正时,进程释放占用资源,sem_op值加到信号量值。

sem_op为负,获取该信号量控制资源,在信号量值小于sem_op绝对值(资源不满足要求),则:若指定IPC_NOWAIT,则semop出错返回EAGAIN。若未指定IPC_NOWAIT调用进程进入休眠状态,直到:某些进程释放资源;系统删除该信号量;进程捕捉一个信号。

semop0,表示调用进程希望等到该信号量值变为0,信号量值是0立即返回,非0时,若指定IPC_NOWAIT,则出错返回,若未指定进程休眠情况同上。

int semctl (int semid , int semnum , int cmd, ....../*union semun arg*/)

实现对信号量各种控制操作,semid:要进行操作的信号量集,senum:信号集中的某个信号量可取为GETVALSETVALGETNCNTGETPID。最后一个参数可选取决于第三个参数cmdunion senum {

int val ;  // for SETVAL

struct semid_ds *buf ; //for IPC_SET and IPC_STAT

ushort  *array  //for GETALL  and SETALL 

     }

cmd取值,在semid指定信号集合执行此命令,

IPC_STAT:取信号集的semid_ds结构,并存放arg.buf结构。

IPC_SET:按照arg.buf指向结构中的值,设置此信号集的三个字段,即sem_perm结构体的uidgidmode

IPC_RMID:从系统中删除该信号量集合。

GETVAL:返回成员semnumsemval值。

SETVAL:设置semnumsemval值,该值由arg.val指定。

GETPID:返回semnumsempid.

GETNCNT:返回semnumsemncnt
GETZCNT:返回semnumsemzcnt

GETALL:取信号所有值放入array中。

SETALL:按照array每一个值设置集合中的每个信号量的值。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值