Synchronization 进程同步的信号量

Synchronization 进程同步的信号量,synchronization,operating-system,kernel,semaphore,interrupt,Synchronization,Operating System,Kernel,Semaphore,Interrupt,我对信号量的理解还不够透彻。每一次,我冒险去理解他们,总会有一些我不理解的东西出现 现在我的问题是: 我在“操作系统概念”中读到:“*信号量S是一个整数变量,除了初始化外,只能通过两个标准原子操作来访问:wait()和signal()。”* 原子在这里意味着什么?这是否意味着此操作将一次性执行 但本书接着给出了wait()的一个示例实现: 等待{ 而S是否意味着该操作将一次性执行 基本上,是的 这个例子不是一个实际的实现,(我希望!),只是功能的C风格表示。实际的实现是OS/CPU特定的,因为需

我对信号量的理解还不够透彻。每一次,我冒险去理解他们,总会有一些我不理解的东西出现

现在我的问题是:

我在“操作系统概念”中读到:“*信号量S是一个整数变量,除了初始化外,只能通过两个标准原子操作来访问:wait()和signal()。”*

原子在这里意味着什么?这是否意味着此操作将一次性执行

但本书接着给出了wait()的一个示例实现:

等待{

而S是否意味着该操作将一次性执行

基本上,是的

这个例子不是一个实际的实现,(我希望!),只是功能的C风格表示。实际的实现是OS/CPU特定的,因为需要内核/硬件支持来消除繁忙的等待,并确保在多核处理器上正确操作

Rgds,
Martin

这是否意味着此操作将一次性执行

基本上,是的

这个例子不是一个实际的实现,(我希望!),只是功能的C风格表示。实际的实现是OS/CPU特定的,因为需要内核/硬件支持来消除繁忙的等待,并确保在多核处理器上正确操作

Rgds,
Martin

wait的示例代码只是说明性的,不太可能以这种方式实现。如果计数器不大于零,大多数操作系统都会暂停尝试获取信号量的进程


但是,从技术上讲,这个例子是可行的。如果S被标记为volatile,那么任何其他进程或线程的更改都会被wait()看到。wait()将在一个紧密的循环中旋转,直到满足条件为止,并将占用CPU,但它会工作。请注意,这种CPU占用是操作系统暂停调用线程的原因,因为条件无法满足。您需要以原子方式进行测试和递减,这通常通过使用操作系统原子函数(如Inter)来完成Windows上的LockedCompareeExchange。

等待的示例代码只是说明性的,它不太可能以这种方式实现。如果计数器不大于零,大多数操作系统将暂停尝试获取信号量的进程


但是,从技术上讲,这个例子是可行的。如果S被标记为volatile,那么任何其他进程或线程的更改都会被wait()看到。wait()将在一个紧密的循环中旋转,直到满足条件为止,并将占用CPU,但它会工作。请注意,这种CPU占用是操作系统暂停调用线程的原因,因为条件无法满足。您需要以原子方式进行测试和递减,这通常通过使用操作系统原子函数(如Inter)来完成Windows上的LockedCompareeExchange。

您说,如果S被标记为volatile,那么任何其他进程或线程的更改都会被wait()看到.但我不明白,如果等待是原子的,它将保留CPU本身,那么就没有其他进程有机会修改它的原子。从调用者的角度来看,这取决于wait()的实现来决定如何最好地工作。重要的是当有人调用wait()时它具有原子性的可观察行为。感谢您从调用者的角度指出了这一点。此外,我已经了解到内核将使用诸如自旋锁之类的锁定技术来确保wait()和signal()是以原子方式执行的,即没有两个进程可以同时在同一信号量上执行wait和signal.但我不明白,如果等待是原子的,它将保留CPU本身,那么就没有其他进程有机会修改它的原子。从调用者的角度来看,这取决于wait()的实现来决定如何最好地工作。重要的是当有人调用wait()时它具有原子的可观察行为。感谢您从调用者的角度指出了这一点。此外,我已经了解到内核将使用诸如自旋锁之类的锁定技术来确保wait()和signal()以原子方式执行,即没有两个进程可以在同一信号量上同时执行wait和signal。
wait(S) {
while S <= 0
; // no-op
S--;
}