System V 信号量

在提到Posix 信号量时,指的是二值信号量或计数信号量,而System V信号量指的是入了计数信号量集

二值信号量:其值为0或1,类似于互斥锁,资源被锁住时为0,资源可用为1
计数信号量:其值在0和某个限制值之间的信号量,信号量的值就是可用资源数
计数信号量集:一个或多个信号量构成一个集合,集合中每个元素都是计数信号量(每个集合的信号量数存在一个限制)

semid_ds结构:

内核为每个信号量集维护的信息结构

#include <sys/sem.h>

struct semid_ds{
struct ipc_perm sem_perm; // 当前信号量的访问权限
struct sem *sem_base; // 内核用于维护某个给定信号量的一组值的内部数据结构
ushort sem_nsems; // 集合中信号量的数目
time_t sem_otime; // 最近一次执行semop()的时间
time_t sem_ctime; // 集合创建时间或最近一次IPC_SET的时间
}; struct sem{
ushort_t semval; // 信号量实际值
short sempid; // 对信号量值执行最后一次操作的进程的进程ID
ushort_t semncnt; // 等待信号量值增长的进程数
ushort_t semzcnt; // 等待信号量值变为0的进程数
};

semget()函数:

#include <sys/sem.h>

// 创建一个信号量集或访问一个已存在的信号量集
// 成功返回非负信号量标识符,出错返回-1
int semget(key_t key, int nsems, int oflag);
// key: IPC 键
// nsems:指定集合中信号量数
// oflag:SEM_R(读)和SEM_A(改)的组合,还可以按位与IPC_CREAT或IPC_CREAT|IPC_EXCL

semop()函数:

#include <sys/sem.h>

// 对信号量集中一个或多个信号量进行操作
// 成功返回0,出错返回-1
int semop(int semid, struct sembuf *opsptr, size_t nops);
// semid:由semget()函数返回的信号量标识符
// nops: 指出opsptr指向的结构数组的元素数量
// opsptr:指向一个如下的数组 struct sembuf{
short sem_num; // 信号量集中信号量的索引值:0, 1, ... , nsems-1(sem_base[sem_num], 指定对某个特定信号量进行操作)
short sem_op; // 指定对特定信号量的操作
short sem_flg; // 操作标志,0, IPC_NOWAIT、SEM_UNDO
};
// sembuf结构内元素的排列顺序并不保证如上述那样,只保证该结构中有上述三个元素
// sembuf结构不能静态初始化(struct sembuf value = {0, 0, 0} // Error)
// sembuf结构需要运行时初始化(struct sembuf value; value.sem_num = 0; ...) // sem_op:每个特定的操作有sem_op确定,它可以是负数、0、正数
// sem_op为正数时,其值加到semval(信号量当前值)上,对应于释放信号量控制的资源
// 如果指定了SEM_UNDO标志,就从相应信号量的semadj(所指定信号量针对调用进程的调整值)减去sem_op
// sem_op为0,调用者等待semval变为0,如果semval已经为0,则立即返回
// sem_op为负数,调用者希望等待semval变为大于或等于sem_op的绝对值,这对应于分配资源

semctl()函数:

#include <sys/sem.h>

// 对一个信号量执行各种控制操作
// 成功返回非负值,出错返回-1
int semctl(int semid, int semnum, int cmd, ... /* union semun arg */);
// semid: 标识其操作待控制的信号量集
// semnum: 标识信号量集内的某个成员(sem_base[sem_num]) // cmd:可选值如下(除非另外说明,操作成功函数返回值为0,出错为-1)
// GETVAL:将semval的当前值作为函数返回值返回
// SETVAL:将semval设为arg.val(若操作成功,那么相应信号量的semadj被设为0)
// GETPID:将sempid的当前值作为函数返回值返回
// GETNCNT:将semncnt(等待semval变为大于其当前值的线程数)的当前值作为函数返回值返回
// GETZCNT:将semzcnt(等待semval变为0的线程数)的当前值作为函数返回值返回
// GETALL:返回指定信号量集内每个成员的semval值(这些值通过arg.array指针返回)
// SETALL:设置指定信号量集内每个成员的semval值(这些值通过arg.array指针传递)
// IPC_RMID:将由semid指定的信号量集从系统删除
// IPC_SET:设置指定信号量集的semid_ds结构中的sem_perm.uid、sem_perm.gid、sem_perm.mode,这些值由arg.buf参数指向的结构中的相应成员指定
// IPC_STAT:返回指定信号量集当前的semid_ds结构(通过arg.buf) // arg: 可选参数,根据 cmd 参数而定
union semun{
int val;
struct semid_ds *buf;
ushort *array;
};

System V 信号量使用相关函数的更多相关文章

  1. 第11章 System V 信号量

    11.1 概述 信号量按功能分:二值信号量.计数信号量.信号量集:其中二值信号量和计数信号量指的是Posix信号量,信号量集指的是System V信号量.

  2. System V信号量

    信号量对比 二值信号量:其值要么0要么1,比如互斥锁就是这种类型 计数信号量:其值为0或某个正整数,比如POSIX 信号量 计数信号量:一个或多个信号量构成一个集合,每个都是计数信号量,比如Syste ...

  3. UNIX环境高级编程——system V信号量

    1. 信号量(semaphore)主要用于保护临界资源.进程可以根据它判断是否能访问某些共享资源.信号量除了用于访问控制外,还可用于进程同步,也就是进程间通信.2. 信号量分类:a. 二值信号量: 信 ...

  4. Linux IPC实践(11) --System V信号量(1)

    信号量API #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semget ...

  5. linux网络编程之system v信号量(二)

    今天迎来元旦假期的最后一天了,过得好快~昨天跟小伙伴们在军都滑雪陪儿爽,虽说上了两回中级道都摔得异常的惨烈,但是在初级道上学习"s"转弯还是有一些小心得,可以在要往高手迈进的前提, ...

  6. linux网络编程之system v信号量(一)

    今天起,学习信号量相关的知识,下面开始: 关于信号量,在前面已经介绍过了,这里回顾一下: 通过上面的描述,很容易就能想到信号量的一上数据结构: 下面再来回顾一下P.V原语: 所谓的原语就是指这段代码是 ...

  7. Linux中的System V信号量

    在进程同步,并发运行时,保证按序地访问共享资源是十分重要的.因此引入了临界区的概念,一次只能有一个线程进入临界区完成他的指令.而信号量(semaphore)的作用,类似于一个交通信号灯,它负责进程协作 ...

  8. system V信号量和Posix信号量

    一.函数上的区别 信号量有两种实现:传统的System V信号量和新的POSIX信号量.它们所提供的函数很容易被区分:对于所有System V信号量函数,在它们的名字里面没有下划线.例如,应该是sem ...

  9. Linux IPC System V 信号量

    模型 #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> ftok() //获取key ...

随机推荐

  1. java excutors 四种类型的线程

    http://blog.csdn.net/ochangwen/article/details/53044733

  2. Linux rm删除

    将 test1子目录及子目录中所有档案删除 命令: rm -r test1 rm -rf test2命令会将 test2 子目录及子目录中所有档案删除,并且不用一一确认 命令: rm -rf  tes ...

  3. 九度oj 题目1120:全排列

    题目描述: 给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列. 我们假设对于小写字母有'a' < 'b' < ... < 'y' < 'z',而且给定的字符串中 ...

  4. [Vijos1308]埃及分数(迭代加深搜索 + 剪枝)

    传送门 迭代加深搜索是必须的,先枚举加数个数 然后搜索分母 这里有一个强大的剪枝,就是确定分母的范围 #include <cstdio> #include <cstring> ...

  5. 大数(bzoj 4542)

    /* 想了半天莫队,不知道咋转移,需要动下脑子. 有一个很显然的结论是如果(l,r)是P的倍数,那么s[l...n]%P=s[r+1...n]%P. 根据这个东西,我们预处理出所有的后缀%P的余数,接 ...

  6. Aragorn's Story(hdu3966)

    题意:给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上的所有点权值加上K D C1 C2 K:把C1与C2的路径上的所有点权值减去K Q C:查询节点编号为C ...

  7. max file descriptors [4096] for elasticsearch proess is too low, increase to at least [65536]

    修改文件 /etc/security/limits.conf 加入以下两行: sonar hard nofile 65536 sonar soft nofile  65536 #备注:sonar这里是 ...

  8. WEB学习-CSS基础选择器

    基础选择器 标签选择器 就是标签的名字. • <h1>前端与移动开发<span>1期班</span>基础班</h1> css: • <style ...

  9. Hihocoder 1561 观光旅行(启发式合并+贪心)

    题目链接 Hihocoder 1561 首先对原图求$MST$ 我们发现某条边成为某两个点的关键路径的必要条件是这条边是最小生成树的树边. 所以我们求$MST$的同时进行启发式合并. 把$size$小 ...

  10. ubuntu下安装翻译软件

    原文: http://sixipiaoyang.blog.163.com/blog/static/6232358820144146386437/ Ubuntu下常用的翻译软件有StarDict,Gol ...