第十章 Posix信号量

知乎讨论

通俗的描述信号量,是这么个东西:
每个信号量拥有一个计数器,sem_post()可以使该计数器+1V操作),sem_wait()在计数器不为0时,可以使该计数器-1,否则阻塞直到不为0(P操作)。
而该计数器的存在,就可以限定某个容器中元素的个数。

如果单纯的看效果,互斥量+条件变量可以实现计数器为1的信号量。

优缺点

UNP卷二

作者对于信号量的评价为:

  1. 信号量默认就是进程间共享
    对同一个信号量,加锁和解锁可以在不同的进程或是进程进行。
    而互斥量只能有是由加锁线程解锁,且默认不再进程间共享。
  2. 信号量有与之关联的一个值,计数器
    该值在信号量结构体内部维护。即使消费者还没有阻塞在sem_wait(),该值也会递增。
    相比与条件变量,如果消费者还没阻塞在pthread_cond_wait(),那么由pthread_cond_signal()发送的信号就会丢失,没有函数去处理。
  3. 相比于其他锁,只有sem_port()是异步信号安全函数
    异步信号安全函数指的是:可以在信号处理函数中调用的函数。

muduo陈硕

  1. 信号量不是必备的锁
    使用条件标量和互斥量可以完全代替信号量的功能
  2. 信号量的计数器是个累赘
    程序的容器有自己的长度,而信号量又自带一个,这样造成了同样的信息维护两份,需要时刻保持一致。增大了程序员的负担和出错的可能。
  3. 同时建议使用单独一个线程去分配任务
    其他线程使用条件变量阻塞

个人见解

没有项目经验,不保证全对

  1. 不同线程间可解锁
    这还真可能是个累赘。
  2. 确实可以使用条件变量+互斥量去代替
  3. 异步信号安全函数
    没用过,不知道啊。书上也将,可以在函数内向管道内写东西的方式来激活一个别的线程,解决这些问题。

Posix 信号量

Posix信号量不必在内核中维护。

有名信号量

这个信号量有名字啦,根据这个名字就可以在不同的进程间使用。

这个名字可以时文件系统中对应的名字来表示。

Api

打开/创建有名信号量

#include <semaphore.h>
sem_t sem;
sem_t *sem_open(const char *pathfile, int flag/, mode_t mode ,unsigned int value/);

打开一个信号量
flag:可以时0,主要使用来,当指定的文件不存在时,使用O_CREATE | O_EXEL新建,如果指定为0,后两个参数可省略,否则后面两个参数需要带上。
mode:文件权限。
value:信号量初始的值,这这个参数只有在新创建的时候才需要设置,如果是打开已有的,不需要在去指定,否则会报错。该值不超过是SEM_VALUE_MAX(至少是32767)。
取消对信号量的使用

#include <semaphore.h>
int sem_close(sem_t *sem);
//成功返回0,否则返回-1

这个函数只是声明,在这个进程中不再使用这个信号量,并不是去析构该信号量。
同时进程结束的时候,无论是正常还是信号中断退出进程,内核都会主动调用该函数去关闭进程使用的信号量。
即使都没有后进程在使用这个信号量了,内核也会维持这个信号量。
也就是说,Posix的信号量是随着内核持续的。
主动析构信号量

#include <semaphore.h>
int sem_unlink(const char *name);
//成功返回0,否则-1

对打开的信号量的路径执行,直接删除指定的文件,但是并不析构该信号量。当最后一个使用该信号量的进程调用sem_close()对该信号量的时候,内核析构该信号量。

P操作

#include <semaphore.h>
int sme_wait(sem_t *);
int sem_trywait(sem_t *);
//成功返回0 ,否则-1

sem_wait()测试指定的信号量,如果计数器值大于0,那么递减计数器,并立即返回,否则,阻塞在计数器为0。直到不是0时,递减并返回。如果因为信号中断,则过返回EAGAIN错误。
sem_trywait()函数,如果指定信号量的计数器为0,那么直接返回EAGAIN错误。

为什么阻塞递减叫做P操作?源自荷兰单词proberen意思是尝试。
V操作

#include <semaphore.h>
int sme_post(sem_t *);
//成功返回0 ,否则-1

递增指定的信号量计数器+1
同样因为荷兰单词verhogen增加的意思。

当前计数器的值

#include <semaphore.h>
int sem_getvalue(sem_t *,int *);
//成功返回0 ,否则-1

传入两个参数,第二个参数是需要填充的。
如果当前信号量已经上锁,也就是有线程在等待,那么该值为0或者是负数,而如果是负数,那么表示等待该信号量解锁的线程数。

信号量死锁

主要出现在,如果同时使用两个信号量,那么顺序一定不能出错。

基于内存信号量

不使用文件系统标识,直接存在程序运行的内存中,(非共享内存)。
这样就造成了,不同进程之间不能访问,不能用于不同进程之间相互访问。
一个父进程初始化一个信号量,然后fork其副本得到的是该信号量的副本,这两个信号量之间并不存在关系。
初始化

#include <semaphore.h >
int sem_init(sem_t *sem,int shared,unsignel int value);
//出错返回-1,成功的不一定。
int sem_destory(sem_t *);
//成功0,失败-1;

第二个参数,表示是否在进程件共享,在这种实现中不可能进程间共享,需要基于共享内存的信号量,才可以。
sem_init()需要用户自己创建一个结构体(不是指针)。然后使用该函数去初始化结构体。
sem_open()则可以直接返回一个指针,并不需要去创建这个结构体。

基于共享内存的信号量

和共享内存有关了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容