在数据结构同步的背景下,有人能澄清“无锁”和“非阻塞”的区别吗?这些术语似乎被很多人交替使用,但我还不确定是否有一些微妙的差别隐藏在其中。
我的意思是,无锁是“没有锁”,而非阻塞更像是保证进展。我怀疑一个暗示另一个,但不是相反的情况,我不确定。
欢迎提供参考。
我的意思是,无锁是“没有锁”,而非阻塞更像是保证进展。我怀疑一个暗示另一个,但不是相反的情况,我不确定。
欢迎提供参考。
是的,无锁意味着没有锁定机制。非阻塞意味着调用将立即返回,而不是等待某些外部事件(例如释放锁或数据到达缓冲区)发生。可以使用锁并使用非阻塞调用,例如在调用中。
flock(fh, LOCK_SH | LOCK_NB);
这意味着“尝试获取读锁,但如果无法获取,请不要等待,立即返回并告诉我你无法获取”。没有LOCK_NB
(“非阻塞”)的LOCK_SH
(“共享锁”)的默认行为是等待锁可用。
它们可能相似,但通常在不同的上下文中使用。在数据结构的上下文中,它们将是相同的东西。您还可以在IO的上下文中使用“非阻塞”,在这种情况下,它意味着函数在返回之前不会等待操作完成或者该操作肯定不会被阻塞(例如读取已经被缓存的数据)。
此外,“非阻塞”并不意味着某些东西是无锁的。例如,一个数据结构可能使用锁,但具有一些不需要锁的非阻塞操作和其他需要锁的阻塞操作。
实现方式1:
notify()
原子地设置一个布尔值。 wait()
循环直到布尔值为真。两者都是无锁的,但wait()
是阻塞式的。
实现方式2:
notify()
获取锁,设置布尔值,然后释放锁。 wait()
获取锁,读取布尔值,释放锁,所有这些都在循环中进行,直到布尔值为真。因此,两者都是基于锁的,阻塞式的。
实现方式3:
最初锁被使用。 notify()
检查布尔值,如果为真,则释放锁。 wait()
获取锁并将布尔值设置为true。 notify()
是非阻塞式的(是否是无锁的有争议)。wait()
是基于锁的,阻塞式的。
因此,我会说非阻塞意味着无锁,但它们并不等同,因为无锁操作仍然可以在循环中阻塞条件。