信号量同步-P V 操作

信号是 E. W. Dijkstra 在二十世纪六十年代末设计的一种编程架构。Dijkstra 的模型与铁路操作有关:假设某段铁路是单线的,因此一次只允许一列火车通过。

信号将用于同步通过该轨道的火车。火车在进入单一轨道之前必须等待信号灯变为允许通行的状态。火车进入轨道后,会改变信号状态,防止其他火车进入该轨道。火车离开这段轨道时,必须再次更改信号的状态,以便允许其他火车进入轨道。

在计算机版本中,信号以简单整数来表示。线程等待获得许可以便继续运行,然后发出信号,表示该线程已经通过针对信号执行 P 操作来继续运行。

线程必须等到信号的值为正,然后才能通过将信号值减 1 来更改该值。完成此操作后,线程会执行 V 操作,即通过将信号值加 1 来更改该值。这些操作必须以原子方式执行,不能再将其划分成子操作,即,在这些子操作之间不能对信号执行其他操作。在 P 操作中,信号值在减小之前必须为正,从而确保生成的信号值不为负,并且比该值减小之前小 1。

PV 操作中,必须在没有干扰的情况下进行运算。如果针对同一信号同时执行两个 V 操作,则实际结果是信号的新值比原来大 2。

对于大多数人来说,如同记住 Dijkstra 是荷兰人一样,记住 PV 本身的含义并不重要。但是,从真正学术的角度来说,P 代表 prolagen,这是由 proberen te verlagen 演变而来的杜撰词,其意思是尝试减小V 代表 verhogen,其意思是增加 。Dijkstra 的技术说明 EWD 74 中介绍了这些含义。

sem_wait (3RT) 和 sem_post (3RT) 分别与 Dijkstra 的 PV 操作相对应。sem_trywait (3RT) 是 P 操作的一种条件形式。如果调用线程不等待就不能减小信号的值,则该调用会立即返回一个非零值。

有两种基本信号:二进制信号和计数信号量。二进制信号的值只能是 0 或 1,计数信号量可以是任意非负值。二进制信号在逻辑上相当于一个互斥锁。

不过,尽管不会强制,但互斥锁应当仅由持有该锁的线程来解除锁定。因为不存在“持有信号的线程”这一概念,所以,任何线程都可以执行 Vsem_post (3RT) 操作。

计数信号量与互斥锁一起使用时的功能几乎与条件变量一样强大。在许多情况下,使用计数信号量实现的代码比使用条件变量实现的代码更为简单,如示例 4–14示例 4–15示例 4–16 中所示。

但是,将互斥锁用于条件变量时,会存在一个隐含的括号。该括号可以清楚表明程序受保护的部分。对于信号则不必如此,可以使用并发编程当中的 go to 对其进行调用。信号的功能强大,但是容易以非结构化的不确定方式使用。

命名信号和未命名信号

POSIX 信号可以是未命名的,也可以是命名的。未命名信号在进程内存中分配,并会进行初始化。未命名信号可能可供多个进程使用,具体取决于信号的分配和初始化的方式。未命名信号可以是通过 fork() 继承的专用信号,也可以通过用来分配和映射这些信号的常规文件的访问保护功能对其进行保护。

命名信号类似于进程共享的信号,区别在于命名信号是使用路径名而非 pshared 值引用的。命名信号可以由多个进程共享。命名信号具有属主用户 ID、组 ID 和保护模式。

对于 openretrievecloseremove 命名信号,可以使用以下函数:sem_opensem_getvaluesem_closesem_unlink 。通过使用 sem_open ,可以创建一个命名信号,其名称是在文件系统的名称空间中定义的。

有关命名信号的更多信息,请参见 sem_opensem_getvaluesem_closesem_unlink 手册页。

计数信号量概述

从概念上来说,信号量是一个非负整数计数。信号量通常用来协调对资源的访问,其中信号计数会初始化为可用资源的数目。然后,线程在资源增加时会增加计数,在删除资源时会减小计数,这些操作都以原子方式执行。

如果信号计数变为零,则表明已无可用资源。计数为零时,尝试减小信号的线程会被阻塞,直到计数大于零为止。

表 4–7 信号例程

操作

相关函数说明

初始化信号

sem_init 语法

增加信号

sem_post 语法

基于信号计数阻塞

sem_wait 语法

减小信号计数

sem_trywait 语法

销毁信号状态

sem_destroy 语法

 

由于信号无需由同一个线程来获取和释放,因此信号可用于异步事件通知,如用于信号处理程序中。同时,由于信号包含状态,因此可以异步方式使用,而不用象条件变量那样要求获取互斥锁。但是,信号的效率不如互斥锁高。

缺省情况下,如果有多个线程正在等待信号,则解除阻塞的顺序是不确定的。

信号在使用前必须先初始化,但是信号没有属性。

 

 

P -  1

V + 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值