Concurrency 共享内存并发算法与互斥体/信号量之间的关系

Concurrency 共享内存并发算法与互斥体/信号量之间的关系,concurrency,synchronization,semaphore,shared-memory,Concurrency,Synchronization,Semaphore,Shared Memory,我试图找出基于共享内存的并发算法(Peterson's/Bakery)与信号量和互斥量的使用之间的关系 在第一种情况下,我们有一个没有操作系统干预的系统,进程可以使用共享内存和繁忙等待来同步它们自己 在第二种情况下,操作系统为进程/线程提供了阻塞能力,而不必忙着等待 是否曾经有过这样的情况:除了信号量之外,我们还想使用共享内存(以确保公平性/不受饥饿),或者操作系统提供了更好的方法来实现这一点 (我想知道一般的概念,但是特定于POSIX/Win32/JAVA线程的答案也很有趣) 非常感谢 我想不

我试图找出基于共享内存的并发算法(Peterson's/Bakery)与信号量和互斥量的使用之间的关系

在第一种情况下,我们有一个没有操作系统干预的系统,进程可以使用共享内存和繁忙等待来同步它们自己

在第二种情况下,操作系统为进程/线程提供了阻塞能力,而不必忙着等待

是否曾经有过这样的情况:除了信号量之外,我们还想使用共享内存(以确保公平性/不受饥饿),或者操作系统提供了更好的方法来实现这一点

(我想知道一般的概念,但是特定于POSIX/Win32/JAVA线程的答案也很有趣)


非常感谢

我想不出在什么情况下,你真正想要的是忙碌的等待。繁忙的等待只会消耗处理器时间,而不会产生任何效果。这并不是说“忙等待”算法没有用处(它们是有用的),但“忙等待”部分不是所需的属性,它只是所需属性的必然结果

彼得森的锁算法和兰波特的面包店算法基本上只是互斥概念的实现。操作系统设施提供了相同概念的实现,但有不同的权衡

互斥锁的“理想”实现将具有“零开销”——如果互斥锁当前未被拥有,则获取互斥锁不会花费任何时间,等待的线程将在前一所有者释放锁的瞬间唤醒,同时,等待的线程不会占用任何处理器时间

“忙等待”或“自旋锁”算法用等待线程使用的处理器时间换取缩短的唤醒时间。如果线程当前在处理器上调度,则忙碌的服务员将以处理器传输获取锁和同步线程所需数据的速度醒来,但在等待时,它将消耗其分配的最大处理器时间。如果线程的数量超过可用处理器的数量,那么这可能会占用当前拥有互斥锁的线程的时间,从而延长等待时间。然而,在某些情况下,解锁和锁定之间的低延迟值得权衡

另一方面,使用操作系统设施将等待线程置于睡眠状态的“阻塞”互斥体具有不同的权衡。在这种情况下,解锁互斥锁和等待线程获取互斥锁之间的时间可能非常长,可能比繁忙等待算法大几百倍。好处是等待线程在等待时确实不消耗处理器时间,因此操作系统可以在线程等待时安排其他工作。因此,这可能会减少总体等待时间,并增加系统的总体吞吐量


一些互斥锁实现使用忙等待和阻塞的组合:它们忙等待很短的时间,如果无法在短时间内获得锁,则切换到阻塞。如果在线程开始等待后不久释放锁,那么这具有快速唤醒的好处,而如果线程必须等待很长时间,则不需要占用处理器时间。它还有一个缺点,短时间等待时处理器使用率高,长时间等待时唤醒速度慢。

谢谢!有一件事我不太确定:彼得森/面包店的算法提供了公平性。互斥体,不一定(例如,POSIX线程在释放互斥体时唤醒一个随机等待的线程)。这通常是如何解决的?操作系统互斥是故意“不公平”的,因此操作系统可以唤醒优先级最高的线程,或者最近处理器时间最少的线程,等等。目标是获得最佳的总体吞吐量。