什么是一般信号量范围?

时间:2013-12-18 11:00:20

标签: c linux operating-system semaphore

一般信号量的范围是多少。我知道它可以采取负值,0和1。 负值表示块队列中阻塞的进程数。 0表示没有进程在块中,1表示有一个资源可用,没有进程抢占它我想知道它是否可能有大于1的值。(例如2)它是什么意思?这是否意味着我们为单个信号量提供了多个资源?

4 个答案:

答案 0 :(得分:6)

您应该准确指定您正在谈论的信号量类型。 Linux支持内核信号量,POSIX信号量和System V信号量。

System V信号量API记录了信号量值不能小于0.

POSIX信号量API记录“如果sem被锁定,则sval点的对象应设置为零或负数,其绝对值表示在某些未指定时间等待信号量的进程数电话“。看起来POSIX信号量的glibc实现不允许信号量计数/值降到零以下。

Linux内核信号量曾经有一个实现跟踪使用负数的服务员 - 这是Bovet& Sons中记录的实现。 Cesati的“了解Linux内核”一书。然而,在2.6内核的演变中(我认为在2.6.11之后和2.6.32之前),实现发生了变化,因此信号量值不会降到零以下。

因此,所有信号量都允许大于零的计数,这表示可以同时获取的一些资源。信号量计数是否可以低于零是一个实现细节 - 在等待资源时这些信号量的行为与信号量实现相同,不会让计数降到零以下。

但信号量大于1的用例很有用。正如Linus Torvalds在新闻组发帖(http://yarchive.net/comp/linux/semaphores.html)中所说:

  

然而,几乎所有信号量的实际使用都是一种特殊情况   计数器初始化为1,并将其用作   简单的互斥,只允许一个用户进入关键   区域。这样的信号量通常被称为“互斥”信号量   相互排斥。

     

我从来没有真正看到任何人使用更复杂的情况   信号量,虽然我知道它可能有用的情况。对于   例如,使用更复杂的信号量就像“油门”一样   你做这样的事情:

/* Maximum concurrent users */    #define MAX_CONCURRENT_USERS 20
struct semaphore sem;

init_sema(&sem, MAX_CONCURRENT_USERS);
     

然后每个用户在开始之前对信号量执行down()   操作。在你有20个用户之前它不会阻止 - 你没有   创建了一个互斥,但你已经创建了一个限制   机制。见

答案 1 :(得分:4)

否定,信号量上正好排队了-N个线程。

,没有等待的线程,等待操作会将调用线程排入队列。

肯定,没有等待线程,等待操作不会将调用线程排入队列。

enter image description here

计数信号量通常用作离散数量的资源保护。例如,计数器可以表示循环队列中使用的槽的数量,生产者线程在插入队列中的项目时“发信号”信号量,消费者线程将“等待”项目出现在队列中,这将确保不如果没有可用的项目,消费者将能够从队列中获取项目。

最大数量取决于系统。信号量可以使用文件描述符实现,在这种情况下,应用程序至少可以打开{OPEN_MAX}个文件和信号量。

您可以通过以下方式检查系统上的当前值:cat /proc/sys/fs/file-max

答案 2 :(得分:0)

思考信号量的一种常见方式是用一个带球的篮子的类比。如果篮中有一个球,则该过程或任务可以从篮子中取球并获得对共享资源或共享执行空间的访问权。

enter image description here

从篮筐中取球代表倒计时信号量,反之亦然,将球放入篮筐是计算信号量的类比。它可以用于互斥,同步和其他情况。

信号量除了它只是整数值并受平台整数实现的限制外,通常没有特定的限制。

根据您的具体用例,信号量是否实际上可以达到值> 1,在某些情况下,它可能和其他人可以想象信号量不能大于1,但是范围将取决于信号量的具体用途。

答案 3 :(得分:0)

它被称为计数信号量。 例如: - 你有一个共享内存的关键部分,你已经将计数信号量初始化为10,这意味着一次只有最多10个进程可以进入临界区进行读取。 并且用于写入临界区使用二进制信号量,并使用上述和二进制信号量的组合在读取时访问该区域。

例如: - 写入递减时,二进制信号量计数器为0,读取过程只检查二进制信号量计数器if(0)等待(1)准备好读取。