自旋锁是免费的吗?

du3*_*369 5 multithreading lock-free spinlock

我对这两个概念有点困惑.

在wiki上无锁的定义:

如果保证系统范围的进度,则非阻塞算法是无锁的

非阻塞的定义:

如果任何线程的故障或暂停不会导致另一个线程的失败或暂停,则算法称为非阻塞

我以为spinlock是无锁的,或者至少是非阻塞的.但现在我不确定.因为根据定义,"spinlock is not lock-free"对我来说也很有意义.比如,如果持有自旋锁的线程被挂起,那么它将导致其他线程在外面旋转.因此,根据定义,spinlock甚至不是非阻塞,更不用说无锁.

我现在很困惑.谁能清楚解释一下吗?

Pet*_*des 6

任何可以被称为锁定的东西(在当前线程解锁之前从关键部分排除其他线程)根据定义是不锁定的.是的,自旋锁是一种锁.

如果线程在持有锁的同时休眠,则没有其他线程可以获取它并向前进行,并且自旋锁无法阻止此操作.操作系统可以随时取消调度线程,即使它位于关键部分的中间.


请注意,"无锁"与"无等待"不同,所以无锁算法仍然可以有像cmpxchg重试循环这样的东西,但只要一个线程每次都成功,就可以锁定它.

一个无等待的算法甚至不能拥有它,并且最多必须等待竞争原子操作的高速缓存未命中/硬件仲裁.维基百科的非阻塞算法文章更详细地定义了无等待和无锁定.


我认为你混淆了两个"阻塞"的定义.

我想你正在谈论一个尝试获取自旋锁的spin_trylock函数,如果失败而不是旋转则返回错误.因此,这与非阻塞I/O具有非阻塞性:与错误失败而不是等待资源可用性.

这并不意味着系统中的任何线程都会在受自旋锁保护的事物上取得进展. 它只是意味着您的线程可以在再次尝试之前执行其他操作,而不需要使用单独的线程来执行某些操作并等待获取锁定.


在无限循环中旋转计为阻塞/不进行循环.对于这个定义,纯自旋锁和(在OS辅助下)睡眠直到另一个线程解锁之间没有区别.

无锁的定义并不涉及浪费CPU时间/功率来为独立工作腾出空间.


有点相关:获取无竞争的自旋锁不需要系统调用,这意味着它是一个"轻量级"锁.即使在非竞争情况下,某些锁实现也始终使用(相对较慢的)系统调用.请参阅Jeff Preshing的"始终使用轻量级互斥锁"一文.另请阅读Jeff的其他帖子以了解有关无锁编程的更多信息,因为它们非常出色.事实上,[lock-free]标签wiki链接到它们很好.