【问题标题】:Turnstile vs Mutex旋转门与互斥锁
【发布时间】:2024-01-01 10:12:01
【问题描述】:
问题与称为 Turnstile 的同步机制有关。可以在here、here 和here 中找到实现和文档的示例。经过一些研究,我仍然找不到以下问题的答案。
- 闸机解决了什么问题?
- 与互斥锁相比,旋转门有什么优势?
- 线程和闸机之间的所有权关系是什么? (如果有)。
- 如果我们降低这些实现的复杂性,旋转门的最基本的最小结构是什么?
【问题讨论】:
标签:
multithreading
concurrency
operating-system
synchronization
mutex
【解决方案1】:
更彻底地阅读了solaris docs后,我能够掌握基本思想,所以我将回答我自己的问题。
闸机解决了什么问题?
与互斥锁相比,十字转门可以提供什么优势?
线程和闸机之间的所有权关系是什么? (如果有的话)。
Turnstile 可以帮助减少互斥体(或任何其他同步单元)的数量。当我们想用闸门保护一个带有锁的对象时,锁变成了一个轻量级的对象,它将所有操作委托给闸门。每个线程最多可以关联一个旋转栅门。因此#turnstiles ≤ #threads。这种方法有助于减少非活动锁的数量。然而,线程和旋转栅门AFAIK之间没有一些明确的所有权。
如果我们降低这些实现的复杂性,什么是最简单的
旋转栅门的骨骼最小结构?
我们可以通过以下方式实现一个简单的旋转门。
使用get 和put 操作分配Turnstiles 的全局池(显然它必须是线程安全的)。无锁堆栈可以是池的相对简单和有效的实现。 TurnstileLock 是将替换我们的锁和互斥锁并将责任委托给Turnstile 的对象。 TurnstileLock 持有指向 Turnstile 的可空指针。
当某个线程想要进入由TurnstileLock 保护的临界区时,它会检查TurnstileLock.currentTurnstile 是否为空(默认必须为空)。
- 如果为 null,则线程从池中取出旋转栅门并将其分配给
TurnstileLock.currentTurnstile,递增 TurnstileLock.currentTurnstile.waitingCount 并进入临界区。
- 否则线程必须增加
TurnstileLock.currentTurnstile.waitingCount 并等待一些必须通过currentTurnstile 访问的条件变量
当某个线程想要离开临界区(或释放锁)时,它必须检查TurnstileLock.currentTurnstile.waitingCount > 0(递减后)
- 如果是,则需要通知条件变量其他线程正在休眠。
- 否则将
TurnstileLock.currentTurnstile 放回池中并将TurnstileLock.currentTurnstile 设置为null