C 进程如何知道信号量可用

C 进程如何知道信号量可用,c,unix,ipc,semaphore,C,Unix,Ipc,Semaphore,当进程等待信号量时,它进入睡眠状态。 因此,它无法轮询信号量值 内核是否轮询信号量值,如果可用,是否向所有等待它的进程发送信号?如果是这样的话,内核的开销会不会太大 或者signal()调用在内部通知等待信号量的所有进程。 请让我知道这一点。当操作系统被另一个进程告知它已使用信号量时,操作系统会再次调度该进程 信号量只是与OS调度器交互的一种方式 内核不轮询信号量;不需要。每次进程调用sem\u post()(或等效程序)时,都会涉及到与内核的交互。内核在sem\u post()过程中所做的是查

当进程等待信号量时,它进入睡眠状态。 因此,它无法轮询信号量值

内核是否轮询信号量值,如果可用,是否向所有等待它的进程发送信号?如果是这样的话,内核的开销会不会太大

或者signal()调用在内部通知等待信号量的所有进程。
请让我知道这一点。

当操作系统被另一个进程告知它已使用信号量时,操作系统会再次调度该进程

信号量只是与OS调度器交互的一种方式

内核不轮询信号量;不需要。每次进程调用
sem\u post()
(或等效程序)时,都会涉及到与内核的交互。内核在
sem\u post()
过程中所做的是查找以前在同一信号量上调用的
sem\u wait()
。如果一个或多个进程调用了
sem\u wait()
,它将选择优先级最高的进程并对其进行调度。这显示为
sem_wait()
最终返回,该进程继续执行

这是如何在引擎盖下实现的

从根本上说,内核需要实现一种称为“原子测试和设置”的东西。这是一种操作,通过某些变量的值可以进行测试,如果满足某个条件(例如值==0),则会改变变量值(例如值=1)。如果成功,内核将做一件事(如调度进程),如果不成功(因为条件值==0为false),内核将做一些不同的事情(如将进程放在不调度列表上)。“原子”部分是在没有其他任何东西能够同时查看和更改同一变量的情况下做出此决定

有几种方法可以做到这一点。一种是挂起所有进程(或者至少是内核中的所有活动),这样就不会有其他任何东西同时测试变量的值。那不是很快

例如,Linux内核曾经有一个叫做大内核锁的东西。我不知道这是否用于处理信号量交互,但这是操作系统用于原子测试集的一种方式

现在CPU有原子测试和设置操作码,这要快得多。好极了的“摩托罗拉68000”早就有了这样一款手机;像PowerPC和x86这样的CPU需要很多很多年才能得到同样的指令

如果你深入linux,你会发现有人提到futexes。futex是一种快速互斥-它依赖CPU的测试/设置指令来实现快速
互斥
信号量

在硬件中发布信号量

变体是邮箱信号量。这是信号量的一种特殊变体,在某些系统类型中非常有用,在这些系统类型中,硬件需要在DMA传输结束时唤醒进程。邮箱是内存中的一个特殊位置,当写入时会引起中断。内核可以将其转换为信号量,因为当该中断被触发时,它会经历与被称为
sem\u post()
的动作相同的动作

这是难以置信的方便;一台设备可以
DMA
将大量数据传输到预先安排好的缓冲区,最后再将少量
DMA
传输到邮箱。内核处理中断,如果一个进程先前在邮箱信号量上调用了
sem\u wait()
,那么内核将对其进行调度。进程也知道这个预先安排好的缓冲区,然后可以处理数据

在实时DSP系统上,这是非常有用的,因为它速度非常快,延迟非常低;它允许进程以很小的延迟从某个设备接收数据。另一种选择是,使用
read()
/
write()
将数据从设备传输到进程的完整设备驱动程序堆栈相比之下速度非常慢

速度

信号量交互的速度完全取决于操作系统

对于Windows和Linux这样的操作系统,上下文切换时间相当慢(如果不是几十微秒的话,也可以是几微秒)。基本上,这意味着当一个进程调用类似于
sem_post()
的东西时,内核正在做很多不同的事情,同时它还有机会最终将控制权返回给进程。在这段时间里,它所做的几乎可以是任何事情

如果一个程序使用了很多线程,并且它们都使用信号量在它们之间快速交互,那么相当多的时间就浪费在
sem\u post()
sem\u wait()
上。这强调了在调用下一个
sem\u post()
之前,一旦流程从
sem\u wait()
返回,就要做大量的工作

然而,在像VxWorks这样的操作系统上,上下文切换时间非常快。也就是说,当调用sem_post()时,内核中运行的代码很少。结果是,信号量交互的效率要高得多。此外,像VxWorks这样的操作系统是以这样的方式编写的,以保证完成所有这些工作所需的时间是恒定的

这会影响这些系统上的软件架构。在VxWorks上,上下文切换很便宜,让大量线程都执行相当小的任务几乎没有什么损失。在Windows/Linux上,重点更多地放在相反的方面

这就是为什么像VxWorks这样的操作系统非常适合硬实时应用程序,而Windows/Linux则不然

Linux PREEMPT_RT补丁集的部分目的是改善Linux内核在运行期间的延迟
I have a very basic doubt.