1.概述

信号量是一种计数器,用来控制对多个进程共享的资源所进行的访问。它们常被用做一个锁机制。

2.相关数据结构与函数

信号量数据结构:

structsemun

{

intval;//当执行SETVAL命令时,用于指定要把信号量设置成什么值。

structsemid_ds *buf;//当执行命令IPC_STAT/IPC_SET,代表内核中所使用的内部信号量数据结构的一个复制。

unsignedshrot *array;//用在GETALL/SETALL命令中的一个指针。

structseminfo *__buf; //信号量内部结构,内部使用,Linux操作系统特有的。

};

新建信号量函数semget(),原型如下:

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

semflg是打开信号的方式:

  • IPC_CREAT:如果内核不存在这样的信号量集合,则把它创建出来。

  • IPC_EXCL:与IPC_CREAT一起使用,当信号量存在时,则出错。

信号量操作函数semop(),原型如下:

intsemop(int semid, struct sembuf *sops, unsigned nsops);

其中,sembuf的定义如下:

structsembuf

{

ushortsem_num; //信号量的编号

shortsem_op; //信号量的操作

shortsem_flg; //信号量的操作标志

};

控制信号量参数semctl()

intsemctl(int semid, int semnum, int cmd, …);

cmd的取值如下:

  • IPC_STAT: 获取某个集合的semid_ds结构,并把它存储在semun联合体的buf参数所指定的地址

  • IPC_SET: 设置某个集合的semid_ds结构的ipc_perm成员的值。该命令所取的值是从sumun联合体的buf参数中取到的。

  • IPC_RMID: 从内核中删除该集合。

  • GETALL: 用于获取集合中所有信号量的值。

  • GETNCNT: 返回当前正在等待资源的进程的数目。

  • GETPID: 返回最后一次执行semop调用的进程的PID。

  • GETVAL: 返回集合中某个信号量的值。

  • GETZCNT: 返回正在等待资源利用率达到百分之百的进程数目。

  • SETALL: 把集合中所有信号量的值设置为联合体的array成员所包含的对应值。

  • SETVAL: 把集合中的单个信号量的值设置为联合体的val成员的值。

参数arg代表类型semun的一个实例。

3.实例

/*-------------------信号量操作实例------------------------------*/

#include<stdio.h>

#include<sys/types.h>

#include<sys/sem.h>

#include<sys/ipc.h>

typedefint sem_t;

unionsemun

{

intval;

structsemid_ds *buf;

unsignedshort *array;

}arg;

/*创建信号量*/

sem_tCreateSem(key_t key, int value)

{

unionsemun sem;

sem_tsemid;

sem.val= value;

semid= semget(key, 0, IPC_CREAT | 0666);

if(-1 == semid)

{

printf("createsemaphore error\n");

return-1;

}

semctl(semid,0, SETVAL, sem);

returnsemid;

}

/*增加信号量*/

intSem_P(sem_t semid)

{

structsembuf sops = {0, +1, IPC_NOWAIT};

return(semop(semid, &sops, 1));

}

/*减小信号量*/

intSem_V(sem_t semid)

{

structsembuf sops = {0, -1, IPC_NOWAIT};

return(semop(semid, &sops, 1));

}

/*设置信号量的值*/

voidSetvalueSem(sem_t semid, int value)

{

unionsemun sem;

sem.val= value;

semctl(semid,0, SETVAL, sem);

}

/*获取信号量的值*/

intGetvalueSem(sem_t semid)

{

unionsemun sem;

returnsemctl(semid, 0, GETVAL, sem);

}

/*销毁信号量*/

voidDestroySem(sem_t semid)

{

unionsemun sem;

sem.val= 0;

semctl(semid,0, IPC_RMID, sem);

}

intmain(int argc, char *argv[])

{

key_tkey;

intsemid;

chari;

structsemid_ds buf;

intvalue = 0;

key= ftok("/ipc/sem", 'a');

semid= CreateSem(key, 100);

for(i= 0; i <= 3; i++)

{

Sem_P(semid);

Sem_V(semid);

}

value= GetvalueSem(semid);

printf("信号量值为:%d\n",value);

DestroySem(semid);

return0;

}

转载于:https://my.oschina.net/fuyajun1983cn/blog/263926

专题 13 IPC之信号量相关推荐

  1. 远控免杀专题(13)-zirikatu免杀(VT免杀率39/71)

    声明:文中所涉及的技术.思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担! 本专题文章导航 1.远控免杀专题(1)-基础篇:https://mp.w ...

  2. Linux进程间通信第四讲 标准IPC之信号量集

    目录 4.3信号量集 4.3.1 概念和原理 4.3.2 使用 4.3信号量集 4.3.1 概念和原理 (不是用于进程间传递数据.而是用于进程间访问控制) 信号量集是一个信号量的集合,可以存放多个信号 ...

  3. 专题 14 IPC之共享内存

    1.概述 共享内存是在多个进程之间共享内存区域的一种进程间的通信方式,它是在多进程之间对内存段进行映射的方式实现内存共享的.这是IPC最快捷的方式,共享内存方式的通信过程没有中间过程,共享内存直接将某 ...

  4. 专题 12 IPC之消息队列

    1.概述 消息队列是内核地址空间中的内部链表,通过Linux内核在各个进程之间传递内容.消息顺序地发送到消息队列中,并以几种不同的方式从队列中获取,每个消息队列可以用IPC标识符唯一的进行标识.内核中 ...

  5. [4G5G专题-13]:功能 LTE非授权频谱辅助接入技术(LAA )详解

    目录 第1章 LTE授权频谱辅助接入LAA概述 1.1 什么是授权频谱与非授权频谱? 1.2 LAA概述 1.3 为什么需要LAA 1.4 LAA的频谱 1.5 在5GHz非授权频谱上,ETSI与FC ...

  6. 专题 11 IPC之管道

    1.概述 管道通信是多个进程之间进行的通信方式之一.无名管道用于父进程与子进程之间进行通信的场合,命名管道用于任何两个进程之间的通信场合.管道仅仅是将某个进程的输出和另一个进程的输入相连接的单向通信的 ...

  7. oracle如何获取异常,Oracle专题13之异常错误处理

    异常:是程序在正常执行过程中发生的未预料的事件. b.什么是异常处理? 异常处理是为了提高程序的健壮性,使用异常处理部分可以有效地解决程序正常执行过程中可能出现的各种错误,使得程序正常运行. c.异常 ...

  8. 空间谱专题13:联合解算DOA(ML/AP)

    其中作者:桂. 时间:2017-10-16  07:51:40 链接:http://www.cnblogs.com/xingshansi/p/7675380.html 前言 主要记录二维测向中,分别利 ...

  9. 考研高数 专题13:计算二重积分的方法和技巧

    文章目录: 1.利用直角坐标计算 2.利用极坐标计算 3.利用奇偶性和对称性计算

最新文章

  1. python是高级动态编程语言-python是一种跨平台、开源、免费的高级动态编程语言,对么...
  2. linux链接curl库,Linux利用curl库快速开发http应用
  3. 制作r710 linux系统盘,记一次云主机系统盘扩容及制作私有镜像的操作步骤
  4. 浅谈对离散型随机变量期望的理解
  5. Springmvc入门案例(1)
  6. C#使用Advanced CSharp Messenger
  7. 人工智能时代职教教师能力提升的路径
  8. matlab求含参数一元三次方程,matlab 求解一元三次方程,带其他参数
  9. 另类网站版式设计欣赏
  10. 服务器通过无线modem接入4g网络,24-4G Modem管理配置
  11. 记使用Python+Pandas和Scipy库计算TRIMMEAN(截尾均值)的demo
  12. Airbnb NYC2019分析实战
  13. 天龙八部科举答题问题和答案(全6/8)
  14. 2020年百度运维工程师笔试真题(附答案)
  15. Docker基础30--6.4 Docker三剑客之Swarm
  16. 3-D Quasi-Recurrent Neural Network for Hyperspectral Image Denoising
  17. vivado 2017.4安装步骤
  18. 个人简历应聘优势怎么写? 个人优势让你的简历模板加分
  19. 解决时间机器无法识别硬盘问题
  20. 2020最全Python内置函数大全!赶快收藏起来!

热门文章

  1. java on RHEL5
  2. [推荐]在线测试你的网速
  3. mysql 学习笔记(二)
  4. Python打包PyPI上传实践
  5. [Python3网络爬虫开发实战] 1.7.1-Charles的安装
  6. JavaScript 之 typeof
  7. PHP设计模式:观察者模式
  8. 自定义编译gdal库
  9. openblas 矩阵算法库 简介
  10. php 远程代码执行漏洞复现 cve-2019-11043