五种IO模型,同步IO和异步IO
五种 IO 模型
阻塞 IO
非阻塞IO
信号驱动IO
多路转接IO
异步IO
高级 IO 重要概念
同步通信 vs 异步通信(synchronous communication/ asynchronous communication)
同步和异步关注的是消息通信机制.
·所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回. 但是一旦调用返回,就得到返回值了; 换句话说,就是由调用者主动等待这个调用 的结果;
·异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果; 换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果; 而是在调用 发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用.
阻塞 vs 非阻塞
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.
fcntl
一个文件描述符,默认都是阻塞IO
函数的定于如下:
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
传入的 cmd 的值不同, 后面追加的参数也不相同.
fcntl 函数有 5 种功能:
• 复制一个现有的描述符(cmd=F_DUPFD).
• 获得/设置文件描述符标记(cmd=F_GETFD 或 F_SETFD).
• 获得/设置文件状态标记(cmd=F_GETFL 或 F_SETFL).
• 获得/设置异步 I/O 所有权(cmd=F_GETOWN 或 F_SETOWN).
• 获得/设置记录锁(cmd=F_GETLK,F_SETLK 或 F_SETLKW).
实现函数 SetNoBlock
基于 fcntl, 我们实现一个 SetNoBlock 函数, 将文件描述符设置为非阻塞.
轮询方式读取标准输入
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
void SetNoBlock(int fd) {int fl = fcntl(fd, F_GETFL);if (fl < 0) {perror("fcntl");return;}fcntl(fd, F_SETFL, fl | O_NONBLOCK);
}
int main() {SetNoBlock(0);while (1) {char buf[1024] = { 0 };ssize_t read_size = read(0, buf, sizeof(buf) - 1);if (read_size < 0) {perror("read");sleep(1);continue;}printf("input:%s\n", buf);}return 0;
}