C语言-进程——信号量

本文详细介绍了System V信号量的概念、分类和作用,包括临界资源、临界区、P操作和V操作。重点讲解了创建、PV操作和信号量属性管理的API,如semget、semop和semctl,并提供了相关示例代码。通过这些内容,读者可以深入理解如何使用System V信号量来协调进程间的资源访问。
摘要由CSDN通过智能技术生成

system-V的信号量其实是一个信号量数据,一个sysyem-V代表的是一个或多个信号量元素

信号量本质上是一个数字,用来表征一种资源数量,当多个进程或线程争夺这些稀缺资源的时候,信号量用来保证他们合理地、秩序地使用这些资源。

信号量SEM,不是用来传输数据的,而是作为“旗语”,用来协调个进程或者而线程工作的。

1信号量分类

  1. ststem-V信号量
  2. POSIX有名信号量
  3. POSIX无名信号量

2一些基本概念

  1. 临界资源:也叫共享资源,多个进程或线程有可能同时访问的资源(变量、链表、文件等等)
  2. 临界区:访问这些资源的代码成为临界代码,这些代码区域区域称为临界区
  3. P操作:程序进入临界区之前之前必须要对资源进行申请,这个动作被称为P操作,简单来说就是申请资源
  4. V操作:程序离开临界区之后必须要释放响应的资源,这个动作被称为V操作,简单来说就是释放资源

3核心API

相同的头文件

#include <sys/types.h> 
#include <sys/ipc.h>
#include <sys/sem.h>

3.1创建SEM

功能:获取信号量ID

int semget(key_t key,int nsems,int semflg);

参数:

  • 返回值:
    • 成功:信号量ID
    • 失败:-1
  • key:信号量的键值
  • nsems:信号量元素的个数
  • semflg:创建选项
    • IPC_CREAT:如果key对应的信号量不存在,则创建
    • IPC_EXCL:如果key对应的信号量存在,则报错
    • mode:信号量的访问权限

创建信号量时,还受到一下系统信息的影响

  1. SEMMNI:系统中信号量的总数最大值
  2. SEMMSL:每个信号量中信号量元素的个数最大值
  3. SEMMNS:系统中素有信号量中的信号量元素的总数最大值

实例代码:

int main(void) 
{ 
    key_t key = ftok(".",1); 
    int semid = semget(key,2,IPC_CREATE|0666); 
}

3.2PV操作

功能:对信号量进行PV操作,或者等零操作

int semop(int semid,struct sembuf sops[],unsigned nsops);

参数:

  • 返回值:
    • 成功:0
    • 失败:-1
  • semid:信号量ID
  • sops:信号量操作结构体数组
  • nsops结果体数组元素个数
  1. 信号量操作结构体
struct sembuf { 
    unsigned short sem_num;//信号量元素序号     
    short sem_op;//操作参数 
    short sem_flg;//操作选项 
}
  1. 根据sem_op的值,信号量操作分为3中情况:
    1. sem_op>0:V操作
    2. sem_op=0:等零操作
    3. sem_op

示例代码

int main() { 
    key_t key = ftok(".", 1); // 创建(若已有则打开)一个包含2个元素的信号量组 
    int id = semget(key, 2, IPC_CREAT|0666); // 定义包含两个P/V操作的结构体数组 
    struct sembuf op[2]; 
    op[0].sem_num = 0; // 信号量元素序号 
    op[0].sem_op = -2; // P操作 
    op[0].sem_num = 0; // 选项默认0 
    op[1].sem_num = 1; // 信号量元素序号 
    op[1].sem_op = +3; // V操作 
    op[1].sem_num = 0; // 选项默认0 
    // 同时对第0、1号信号量元素分别进行P、V操作 
    semop(id, op, 2);
}

3.3 获取或设置信号量的相关属性

int semctl(int semid,int semnum,int cmd....)

参数:

  • semid:信号量ID
  • semnum:信号量元素序号
  • cmd
    • IPC_STAT:获取属性信息
    • IPC_SET:设置属性信息
    • IPC_RMID:立即删除该信号量,参数semnum将被忽略
    • IPC_INFO:获得关于信号量的系统限制信息
    • SEM_INFO:获得系统为共享内存消耗的资源信息
    • SEM_STAT:获得系统中所有SEM的相关信息
    • GETALL:返回所有信号量元素的值,参数semnum将被忽略
    • GETNCNT:返回正阻塞在对该吸纳后量元素P操作的进程总数
    • GETPID:返回最后一个队该信号量元素操作的进程PID
    • GETVAL:返回该信号量元素的值
    • GETZCNT:返回正阻塞对该信号量元素等零操作的进程总数
    • SETALL:返回所有信号量元素的值,参数semnum将被忽略
    • SETVAL:设置该信号量元素的值
  • 返回值
    • GETNCNT:semncnt
    • GETPID:sempid
    • GETVAL:semval
    • GETZCNT:semzcnt
    • IPC_INFO:内核中记录所有SEM信息的数组的下标最大值
    • SEM_INFO:同IPC_INFO
    • SEM_STAT:内核中看i路所有SEM信息的数组
    • 失败:-1
  1. 这是一个变参函数,根据cmd的不同,可能需要第四个参数,第四个参数是一个如下所示的联合体,用户需要自己定义
union semun { 
    int val;//当cmd为SERVAL时使用 
    struct semid_ds *buf;//当cmd为IPC_STAT或IPC_SET时使用 
    unsigned short *array;//当cmd为GETALL或SETALL时使用 
    struct seminfo *_buf;//当cmd为IPC_INFO时使用 
}
  1. 当cmd为IPC_STAT或IPC_SET时,需要用到一下属性信息结构体
struct semid_ds { 
    struct ipc_perm sem_perm;//权限相关信息 
    time_t sem_otime;//最后一次semop()的信息 
    tien_t sem_ctime;//最后一次状态改变时间 
    unsigned short sem_nsems;//信号量元素个数 
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想敲代码的羊羊羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值