在阻塞 I/O 模型中,当应用程序发起 I/O 操作时,整个进程会被阻塞,直到操作完成。在这个过程中,应用程序无法执行其他任务,必须等待 I/O 操作的完成。
特点:
非阻塞 I/O 模型允许应用程序在发起 I/O 操作时立即返回,即使数据尚未准备好。应用程序可以在等待 I/O 完成的同时执行其他任务,需通过轮询(多次尝试)来检查 I/O 是否完成。
特点:
I/O 多路复用(如 select
、poll
、epoll
)允许应用程序同时监听多个 I/O 事件,并在任何一个 I/O 操作准备好时被通知。应用程序可以集中处理多个 I/O 操作,从而避免轮询带来的开销。
特点:
信号驱动 I/O 模型中,应用程序发起 I/O 操作并继续执行其他任务,当数据准备好时,内核会通过信号通知应用程序。这种方式允许应用程序避免轮询和阻塞,且能够异步处理 I/O 事件。
特点:
在异步 I/O 模型中,应用程序发起 I/O 操作并立即返回,I/O 操作由内核完成,操作完成后内核通过回调机制通知应用程序。应用程序无需等待 I/O 完成,也无需轮询或处理信号。
特点:
在多线程模型中,服务器为每个客户端连接创建一个独立的线程。每个线程处理客户端的请求,并将处理结果返回给客户端。由于线程是在同一进程内执行的,因此它们共享内存空间和其他资源。
在多进程模型中,服务器为每个客户端连接创建一个独立的进程。每个进程在自己的内存空间中运行,处理来自客户端的请求并返回结果。由于进程是独立的,数据不会在进程之间共享。
fcntl()
原型:int fcntl(int fd, int cmd, ... /* arg */ );
用法:
fcntl()
函数获取文件描述符的当前标志。 F_GETFL
作为 cmd
参数来实现。O_NONBLOCK
添加到当前标志中。fcntl()
函数将新的标志设置回文件描述符。 F_SETFL
作为 cmd
参数来实现要将文件描述符设置为信号驱动模式,可以使用 fcntl()
函数。
fcntl()
原型:int fcntl(int fd, int cmd, ... /* arg */ );
用法:
fcntl()
函数获取文件描述符的当前标志。 F_GETFL
作为 cmd
参数来获取当前标志。O_ASYNC
标志添加到文件描述符的当前标志中。 F_SETFL
作为 cmd
参数,并将 O_ASYNC
与现有标志结合来实现。fcntl()
设置信号接收进程或进程组: F_SETOWN
作为 cmd
参数,并传递要接收信号的进程 ID 或进程组 ID。这样,当文件描述符有 I/O 事件发生时,系统将向指定进程发送 SIGIO
信号。
在信号驱动 I/O 中,当文件描述符准备好时,会触发 SIGIO
信号。应用程序需要设置信号处理程序来处理该信号。
sigaction()
原型:int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
用法:
sigaction()
函数为 SIGIO
信号设置一个处理函数。通过 sigaction()
配置 SIGIO
信号的处理程序后,应用程序在文件描述符准备好进行 I/O 操作时会自动收到通知并调用处理程序。