我对这两个概念感到有些困惑。
在wiki上定义无锁:
如果有保证,非阻塞算法是无锁的 全系统进展
非阻塞的定义:
如果任何失败或暂停,算法称为非阻塞 线程不能导致另一个线程失败或暂停
我认为spinlock是无锁的,或者至少是非阻塞的。但现在我不确定。因为根据定义,"spinlock is not lock-free"
对我也有意义。比如,如果持有自旋锁的线程被挂起,那么它将导致其他线程在外面旋转。因此,根据定义,spinlock
甚至不是非阻塞的,更不用说无锁定了。
我现在很困惑。任何人都可以清楚地解释清楚吗?
答案 0 :(得分:5)
任何可以被称为锁的东西(在当前线程解锁之前从关键部分排除其他线程)根据定义是不锁定的。是的,自旋锁是一种锁。
如果线程在持有锁的情况下休眠,则没有其他线程可以获取它并向前进展,并且自旋锁无法阻止此操作。操作系统可以随时取消调度线程,即使它位于关键部分的中间。
请注意"无锁"与#34;无等待"相同的事情,所以无锁算法仍然可以有像cmpxchg重试循环这样的东西,但只要一个线程每次成功,它就会成功锁定免费。
无等待算法甚至不能拥有它,并且最多必须等待竞争原子操作的高速缓存未命中/硬件仲裁。维基百科non-blocking algorithm article更详细地定义了无等待和无锁定。
我认为你正在混淆"阻止"的两个定义。
我认为您正在谈论尝试获取自旋锁的spin_trylock
函数,如果失败而不是返回错误纺纱。因此,这与非阻塞I / O在同一意义上是非阻塞的:失败而不是等待资源可用性。
这并不意味着系统中的任何线程都在使用自旋锁保护的东西上进行进展。这只是意味着你的线程可以去做在再次尝试之前的其他事情,而不是需要使用单独的线程并行等待获取锁定。
在无限循环中旋转计为阻止/不进行进度。对于这个定义,纯自旋锁和(在OS辅助下)睡眠直到另一个线程解锁之间没有区别。
锁定的定义并不涉及浪费CPU时间/功率来为独立工作腾出空间。
有点相关:获得无竞争的自旋锁并不需要系统调用,这意味着它是一个轻量级的"锁。即使在非竞争情况下,某些锁实现也始终使用(相对较慢的)系统调用。请参阅Jeff Preshing's Always Use a Lightweight Mutex文章。另请阅读Jeff的其他帖子,了解有关无锁编程的更多信息,因为它们非常出色。实际上,[lock-free]标签wiki链接到它们很好。