Multithreading 什么保证多处理器上具有自旋锁的线程在不同的处理器上运行
我知道自旋锁只能在多处理器上工作。但是,如果两个线程试图获取相同的资源,而其中一个线程被置于自旋锁上,那么是什么阻止了另一个线程不在同一个处理器上运行呢?如果发生这种情况,带有自旋锁的一个将阻止持有资源的一个超过。在这种情况下,它会变成死锁。操作系统如何防止这种情况发生?首先介绍一些背景事实:Multithreading 什么保证多处理器上具有自旋锁的线程在不同的处理器上运行,multithreading,operating-system,spinlock,tbb,Multithreading,Operating System,Spinlock,Tbb,我知道自旋锁只能在多处理器上工作。但是,如果两个线程试图获取相同的资源,而其中一个线程被置于自旋锁上,那么是什么阻止了另一个线程不在同一个处理器上运行呢?如果发生这种情况,带有自旋锁的一个将阻止持有资源的一个超过。在这种情况下,它会变成死锁。操作系统如何防止这种情况发生?首先介绍一些背景事实: 自旋锁(通常是锁)不限于多处理器系统。它们在单处理器上运行良好,甚至单线程应用程序也可以使用它们而不会造成任何伤害 自旋锁不仅由操作系统提供,还具有纯用户空间实现。例如,提供 默认情况下,没有任何东西可
- 自旋锁(通常是锁)不限于多处理器系统。它们在单处理器上运行良好,甚至单线程应用程序也可以使用它们而不会造成任何伤害
- 自旋锁不仅由操作系统提供,还具有纯用户空间实现。例如,提供
- 默认情况下,没有任何东西可以阻止线程在任何可用CPU上运行(无论它们使用的锁是什么)
- 有可重入/递归类型的锁。这意味着,如果一个线程获取了它一次,并尝试在不释放的情况下再次获取它,它将成功,而不是像通常的锁一样死锁。但这并不意味着仅仅因为不同的线程被调度到同一个CPU,它们就适用于不同的线程。对于任何类型的锁,如果一个软件线程锁定了互斥锁,其他线程都必须等待
正如你所看到的,把时间花在无望的等待上不是很有效。因此,在多次尝试获取自旋锁后,更复杂的实现会调用操作系统寻求帮助,以便自愿将其时间片提供给其他线程,这些线程可能会解锁当前线程。谢谢Anton!正如您所说的,单处理器的自旋锁可以工作,但并不有效。在多核系统上,一个线程旋转等待另一个线程运行以释放锁更有意义。如果另一个线程没有运行,最好使用互斥。它是Solaris中的自适应互斥。如果我在多处理器系统上使用spinlock时没有像Solaris这样的操作系统,我想用户有责任检查持有锁的其他线程是否在同一个内核上运行或休眠。因为如果是这种情况,互斥锁将更有效。pthread_互斥锁在Linux上也是自适应的(至少是这样):它首先尝试在用户模式下获得锁,然后转到操作系统。正如我所说的,如果在多次尝试后锁没有被获取,自旋锁可以调用操作系统。检查另一个线程的状态似乎很繁重,而且无论如何都可能调用操作系统,这会破坏自旋锁的好处。我怀疑是否有任何严重的互斥实现在几个周期左右都不会自旋。内核调用很昂贵,而且大多数锁都是无争用的。Windows关键部分也会这样做。同样,我怀疑您是否可以从用户代码中检查其他线程的状态,这样做“优化”将首先删除旋转锁的所有原因。@user2900385,如果答案有帮助,您可能希望接受/向上投票,谢谢:)