我对这两个概念有点困惑。
wiki上无锁的定义:
一个非阻塞算法是无锁的,如果有保证的系统范围内的进展。
非阻塞的定义:
如果任何线程的故障或挂起不能导致另一个线程的失败或挂起,则称为非阻塞算法。
我认为spinlock是无锁的,或者至少是非阻塞的。但现在我不确定了。因为从定义上来说,"spinlock is not lock-free"对我来说也是有意义的。例如,如果保持自旋锁的线程被挂起,那么它将导致其他线程在外面旋转。因此,根据定义,spinlock甚至不是非阻塞的,更不用说无锁了.
我现在很困惑。有人能解释清楚吗?
发布于 2016-12-14 16:48:14
任何可以称为锁(在当前线程解锁之前将其他线程从关键部分排除在外)的东西,从定义上来说都不是无锁的。是的,旋锁是一种锁。
如果一个线程在保持锁的同时休眠,那么没有其他线程能够获取它并向前推进,而自旋锁也无法阻止这一点。操作系统可以随时取消线程的调度,即使它位于关键部分的中间。
请注意,“无锁”与“无等待”不是一回事,所以无锁算法仍然可以有cmpxchg重试循环之类的东西,但是只要每次都有一个线程成功,它就没有锁。
一个没有等待的算法甚至不可能做到这一点,而且最多只能等待缓存丢失/竞争原子操作的硬件仲裁。维基百科的非阻塞算法项目更详细地定义了无等待和无锁。
我想你混淆了两个“阻塞”的定义。
我认为您在谈论的是一个spin_trylock 函数,尝试来获取自旋锁,如果它失败而不是旋转,则返回一个错误。因此,这是与非阻塞I/O相同意义上的非阻塞:错误失败,而不是等待资源可用性。
这并不意味着系统中的任何线程都在对受spinlock.保护的东西进行进展--它只是意味着您的线程可以在再次尝试之前执行其他一些事情,而不需要使用单独的线程在等待获取锁的同时执行一些事情。
在一个无限循环中旋转意味着阻塞/不进步。对于这个定义,纯自旋锁和(在操作系统帮助下)睡觉的纯自旋锁没有区别,直到另一个线程解锁为止。
无锁的定义并不是为了浪费CPU的时间/能量来为独立的工作腾出空间。
有些关联:获得一个无竞争的自旋锁不需要系统调用,这意味着它是一个“轻量级”锁。有些锁实现总是使用(相对缓慢的)系统调用,即使在非竞争的情况下也是如此。请参阅Jeff总是使用轻量级互斥文章。还可以阅读Jeff的其他帖子,以了解更多关于无锁编程的知识,因为它们非常优秀。如此好,事实上,无锁标签wiki链接到他们。
https://stackoverflow.com/questions/41146527
复制相似问题