Synchronization 无锁和非阻塞的区别是什么?
在数据结构同步的上下文中,有人能澄清“无锁”和“非阻塞”之间的区别吗?这些术语似乎被很多人互换使用,但我还不确定是否有一些细微的差别隐藏在某个地方 我的意思是无锁是“没有锁”,无阻塞更像是保证进度。我怀疑其中一个暗示着另一个,但不是相反,我不确定Synchronization 无锁和非阻塞的区别是什么?,synchronization,locking,lock-free,nonblocking,Synchronization,Locking,Lock Free,Nonblocking,在数据结构同步的上下文中,有人能澄清“无锁”和“非阻塞”之间的区别吗?这些术语似乎被很多人互换使用,但我还不确定是否有一些细微的差别隐藏在某个地方 我的意思是无锁是“没有锁”,无阻塞更像是保证进度。我怀疑其中一个暗示着另一个,但不是相反,我不确定 欢迎参考。是的,无锁意味着没有锁定机制。非阻塞意味着调用将立即返回,而不是等待某些外部事件(例如释放锁或数据到达缓冲区)发生。可以使用锁和非阻塞调用,例如在调用中 flock(fh, LOCK_SH | LOCK_NB); 这意味着“试着获得一个读锁
欢迎参考。是的,无锁意味着没有锁定机制。非阻塞意味着调用将立即返回,而不是等待某些外部事件(例如释放锁或数据到达缓冲区)发生。可以使用锁和非阻塞调用,例如在调用中
flock(fh, LOCK_SH | LOCK_NB);
这意味着“试着获得一个读锁,但如果你不能,不要等待,立即返回并告诉我你不能”。没有锁的
LOCK\u SH
(“共享锁”)的默认行为是等待锁的可用性。它们完全不同
锁定意味着您使用某种方法来使用锁控制文件访问。这将停止两个进程同时向同一文件写入数据,在另一个进程正在读取数据时停止一个进程的写入,但允许两个进程同时读取数据
阻塞意味着方法将在返回之前等待操作完成
更新
作为对示例请求的响应。。。如果我有时间,我会尝试添加一些例子,但现在,这里有一个可能性的解释
我们有3种执行锁定的方法:
- 没有
- 阻塞。如果锁不可用,请等待
- 非阻塞。如果锁不可用,则失败
- 阻塞。等待缓冲区准备就绪
- 非阻塞。如果我们不能立即读/写,则会失败
open()
和read()
,就会得到阻塞IO。如果我们想要非阻塞IO,我们必须将O\u NONBLOCK
标志传递给open()
,然后read()
将再次返回E\u
而不是阻塞
默认情况下,没有锁定。我们可以使用F_SETLK
或F_SETLKW
调用fcntl()。如果锁不可用,前者会阻塞,后者会因EACCES
或EAGAIN
而失败
我认为有两个可能的混淆点:
- IO可以是阻塞/非阻塞,锁定可以是阻塞/非阻塞
- 除了数据未准备就绪之外,IO请求可能会被阻止,因为另一个进程已锁定该文件
它们可以相似,但通常用于不同的上下文。在数据结构的上下文中,它们是相同的东西。您也可以在IO上下文中使用“非阻塞”,在这种情况下,这意味着函数在返回之前不会等待操作完成,或者操作肯定不会阻塞(例如,读取已缓存的数据)
此外,非阻塞可能并不意味着某些东西是无锁的。例如,一个数据结构可能使用锁,但有一些不需要锁的非阻塞操作和其他确实需要锁的阻塞操作。锁定是一种访问控制机制。我的意思是,当您希望独占访问某个资源时,可以锁定该资源。锁上门,使用房间/做任何你想做的事,现在为其他人解锁房间,以便他们现在可以使用它。当房间被锁上时,没有其他人可以进入房间,因此不能做任何事情
阻塞用于保证数据检索,即除非您没有数据,否则不要返回。在门口/管道/插座(基本上是任何东西)等待,当数据可用时,获取数据并返回
添加--
不要被这些词的字面英语意思弄糊涂了,因为它们都可以在你试图把它们放进去的上下文中巧妙地互换使用。例如--锁定类似于阻止其他人使用相同的资源,而锁定可以将自己(调用函数)锁定到资源,直到数据可用为止
所以锁定仅仅意味着在指定的时间内捕获一个资源(除非取消阻塞)。
而且,阻塞是指您被阻塞,这意味着您无法继续,因为您没有数据继续或继续
通过改变进程状态并等待中断或事件发生来实现它们的方式。通过一个示例给出一个初步答案:
考虑一个对象(称为“事件”),它有两个方法,wait()
和notify()
- 实施1:
notify()
自动设置布尔值<代码>等待()
循环,直到布尔值为真。两者都是无锁的,但wait()
是阻塞的
notify()
获取锁,设置布尔值,然后释放锁wait()
获取锁,读取布尔值,释放锁,所有这些都在一个循环中,直到布尔值为真。因此,两者都是基于锁的,阻塞
notify()
检查布尔值,如果为真,则释放锁wait()
获取锁并将布尔值设置为truenotify()
是非阻塞的(它是否是无锁的都有争议)wait()
是基于锁的,阻塞的