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种执行锁定的方法:

  • 没有
  • 阻塞。如果锁不可用,请等待
  • 非阻塞。如果锁不可用,则失败
和两种执行IO的方法:

  • 阻塞。等待缓冲区准备就绪
  • 非阻塞。如果我们不能立即读/写,则会失败
如果我们正常使用
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()
阻塞的

  • 实施2:

    notify()
    获取锁,设置布尔值,然后释放锁
    wait()
    获取锁,读取布尔值,释放锁,所有这些都在一个循环中,直到布尔值为真。因此,两者都是基于锁的,阻塞

  • 实施3:

    最初,锁正在使用中
    notify()
    检查布尔值,如果为真,则释放锁
    wait()
    获取锁并将布尔值设置为true
    notify()
    非阻塞的(它是否是无锁的都有争议)
    wait()
    是基于锁的,阻塞的

  • 所以我想说,非阻塞意味着无锁,但它们并不等价,因为无锁操作仍然可以阻塞