自学内容网 自学内容网

IO操作同步、异步、阻塞、非阻塞之间的联系

        本质来说,同步,异步,阻塞、非阻塞没有什么必要的关系。同步可以是阻塞的,也可以是非阻塞的;异步也可以是非阻塞的,(也可以是阻塞的, 异步IO其实本质上是非阻塞的,但在特殊情况下,比如系统资源不足或底层实现的问题,可能会出现阻塞的现象)

1. 同步 I/O 和 异步 I/O

  • 同步 I/O:在发起 I/O 操作后,调用方必须等待操作完成,才能继续执行后续的逻辑。换句话说,调用方需要“同步”到 I/O 完成的时刻,才能继续工作。
  • 异步 I/O:调用方发起 I/O 操作后,不需要等待其完成,系统会在 I/O 完成后通过某种方式(如回调、通知)告知调用方结果。调用方在 I/O 处理过程中可以继续执行其他任务。

2. 阻塞 I/O 和 非阻塞 I/O

  • 阻塞 I/O:调用方发起 I/O 操作时,如果数据还没准备好,调用方会被“阻塞”,直到数据准备好为止,期间调用方处于等待状态。
  • 非阻塞 I/O:调用方发起 I/O 操作时,如果数据还没准备好,调用方立即得到一个通知(如错误码 EAGAIN),表示没有数据可读或写,调用方可以去做其他事情,不会被阻塞。

3. 同步 I/O 可以是非阻塞的吗?

答案是:可以。

虽然同步 I/O 通常是阻塞的,但并不是绝对的。我们可以通过设置文件描述符为 非阻塞 模式,使得同步 I/O 操作变为 非阻塞 I/O。在非阻塞模式下,如果 I/O 操作(例如 readwrite)不能立刻完成,系统会返回一个错误(如 EAGAINEWOULDBLOCK),而不是让调用方阻塞等待。

例如,使用 fcntl 设置套接字为非阻塞模式:

int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);

这样即使在进行同步 I/O 操作时,也不会因为数据未准备好而阻塞。

4. 异步 I/O 可以是阻塞的吗?

答案是:一般来说不会

异步 I/O 的核心特性就是调用方不需要等待 I/O 操作完成后再继续执行,因此异步 I/O 本质上是 非阻塞 的。发起 I/O 请求时,系统会立即返回,随后通过回调函数或信号等方式通知调用方 I/O 操作的结果。所以异步 I/O 本质上不会阻塞,它始终意味着调用方无需在发起 I/O 操作时等待结果。

但是也可以阻塞,通知以后依然可以自己阻塞

5.总结:

  • 同步 I/O 可以非阻塞,通过设置文件描述符为非阻塞模式,尽管 I/O 操作需要调用方处理返回值来决定是否再次尝试。
  • 异步 I/O 一般不能阻塞,因为它的定义决定了调用方不需要等待 I/O 完成,始终会立即返回。

常见的IO模型如select,poll,epoll(LT模式)都是同步阻塞的,epoll的ET模式可以设置套接字非阻塞,所以是同步非阻塞的,异步IO是非阻塞的,比如windows下的IOCP就是,但在特殊情况下,比如系统资源不足或底层实现的问题,可能会出现阻塞的现象。


原文地址:https://blog.csdn.net/qq_68245364/article/details/142713178

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!