一般的信号量范围是多less?

一般信号量的范围是什么。 我知道它可以取负值,0和1.负值表示阻塞队列中阻塞的进程的数量。 0表示没有进程处于阻塞状态,1表示有一个资源可用,没有进程抢占它,我想知道是否有可能具有大于1的值(例如2),这是什么意思? 这是否意味着我们有一个以上的信号资源?

你应该明确指出你正在讨论什么样的信号量。 Linux支持内核信号量,POSIX信号量和System V信号量。

System V信号量API文件的信号量值不能小于0。

POSIX信号量API文档说:“如果sem被锁定,那么sval点将被设置为零的对象或者是一个负数,其绝对值代表在调用期间某个非特定时间等待信号量的进程的数量” 。 看起来像POSIX信号量的glibc实现不允许信号计数/值降到零以下。

Linux内核信号量曾经有一个使用负数跟踪等待者的实现 – 这是Bovet&Cesati的“了解Linux内核”一书中记录的实现。 然而,在2.6内核(我认为在2.6.11之后和2.6.32之前的某个时间)的某个时刻,实现发生了改变,所以信号值不会降到零以下。

所以所有的信号量都允许一个大于零的计数,这代表了可以同时获得的一定数量的资源。 信号计数是否可以低于零是一个实现细节 – 就信号量而言,等待资源的行为与不使计数降到零以下的信号量实现相同。

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

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

我从来没有见过任何人使用更复杂的信号灯的情况下,虽然我知道的情况下,它可以是有用的。 例如,一个更复杂的信号量的使用是作为一个“油门”,你做这样的事情:

/* Maximum concurrent users */ #define MAX_CONCURRENT_USERS 20 struct semaphore sem; init_sema(&sem, MAX_CONCURRENT_USERS); 

然后每个用户在开始一个操作之前在信号量上做一个down()。 它不会阻塞,直到你有20个用户 – 你还没有创建一个互斥,但你已经创建了一个节流机制。 看到?

否定的 ,在信号量上正好有N个线程排队。

,没有等待的线程,一个等待操作会把调用线程放在队列中。

积极的 ,没有等待的线程,一个等待操作不会把调用线程放在队列中。

在这里输入图像描述

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

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

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

思考信号量的常见方法是用篮子和球类比。 如果篮子里有一个球,那么这个过程或任务就可以从篮子中拿球,并且可以访问共享资源或共享执行空间。

在这里输入图像描述

从篮筐拿球表示倒计数信号,反之亦然,把一个球放在篮子里就是计算信号量的一个比喻。 它可以用于互相排斥,同步和其他情况。

信号量除了只有整数值以外,并且受平台的整数实现的限制,通常对信号量的值没有限制。

它可以取决于你的具体使用情况,信号量实际上是否可以达到值> 1,在某些情况下可以和其他人可以想象信号量不会大于1,但是这个范围取决于具体的使用的信号量。

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

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