Flynn's Studio

同步与阻塞概念的区别

Word count: 729Reading time: 2 min
2024/02/05

sync/async这组概念和block/unblock这组概念太过于相似,以至于很多时候混用它们。虽然有过于咬文嚼字的嫌疑,但还是写一下在我的理解中他们的区别。

直接解释

同步/异步

关注的是消息通信机制 (synchronous communication/ asynchronous communication) 。

  • 所谓同步,就是在发出一个调用时,在没有得到结果之前, 该调用就不返回。
  • 异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果。

阻塞/非阻塞

关注的是程序在等待调用结果(消息,返回值)时的状态。

  • 阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
  • 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

进程间的场景

进程间的通信是通过 send() 和 receive() 两种基本操作完成的。具体如何实现这两种基础操作,存在着不同的设计。 消息的传递有可能是阻塞的非阻塞的 – 也被称为同步异步

从进程级通信的维度讨论时, 阻塞和同步(非阻塞和异步)就是一对同义词, 且需要针对发送方接收方作区分对待。

  • 阻塞式发送(blocking send)。发送方进程会被一直阻塞, 直到消息被接受方进程收到。
  • 非阻塞式发送(nonblocking send)。 发送方进程调用 send() 后, 立即就可以其他操作。
  • 阻塞式接收(blocking receive)。 接收方调用 receive() 后一直阻塞, 直到消息到达可用。
  • 非阻塞式接受(nonblocking receive)。 接收方调用 receive() 函数后, 要么得到一个有效的结果, 要么得到一个空值, 即不会被阻塞。

系统调用的场景

在 I/O 系统调用层面, 非阻塞 IO 系统调用 异步 IO 系统调用存在着一定的差别, 它们都不会阻塞进程, 但是返回结果的方式和内容有所差别。

  • 一个非阻塞I/O 系统调用 read() 操作立即返回的是任何可以立即拿到的数据, 可以是完整的结果, 也可以是不完整的结果, 还可以是一个空值。
  • 异步I/O系统调用 read() 结果必须是完整的, 但是这个操作完成的通知可以延迟到将来的一个时间点。

结论

因此,非阻塞系统调用(non-blocking I/O system call 与 asynchronous I/O system call) 的存在可以用来实现线程级别的 I/O 并发, 与通过多进程实现的 I/O 并发相比可以减少内存消耗以及进程切换的开销。

CATALOG
  1. 1. 直接解释
    1. 1.1. 同步/异步
    2. 1.2. 阻塞/非阻塞
  2. 2. 进程间的场景
  3. 3. 系统调用的场景
  4. 4. 结论