浅谈操作系统 IO 模式
原创操作系统 IO 模式概述
在计算机系统中,输入输出(Input/Output,简称IO)操作是必不可少的环节,它涉及到数据在硬件设备(如硬盘、网络接口卡等)和内存之间的传输。操作系统的IO模式决定了这些数据传输的效能和质量。本文将简要介绍几种常见的操作系统IO模式。
1. 阻塞IO(Blocking IO)
阻塞IO是最常见的IO模式之一。在这种模式下,当应用程序发起一个IO请求时,它会等待IO操作完成,直到数据被圆满读取或写入。在等待期间,应用程序会被阻塞,无法执行其他任务。
以下是一个明了的阻塞IO示例代码:
c
#include
int main() {
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {
perror("Error opening file");
return 1;
}
char ch;
while ((ch = fgetc(fp)) != EOF) {
putchar(ch);
}
fclose(fp);
return 0;
}
在这个示例中,程序会阻塞直到文件读取完毕。
2. 非阻塞IO(Non-blocking IO)
非阻塞IO允许应用程序在IO操作未完成时继续执行其他任务。在非阻塞模式下,当应用程序发起一个IO请求后,它会立即返回,而不会等待IO操作完成。如果IO操作未完成,应用程序可以定期检查IO状态,或者通过轮询(polling)来获取IO操作的最终。
以下是一个明了的非阻塞IO示例代码:
c
#include
#include
#include
int main() {
int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("Error opening file");
return 1;
}
char ch;
while (read(fd, &ch, 1) > 0) {
putchar(ch);
}
close(fd);
return 0;
}
在这个示例中,程序会立即返回,然后通过循环检查IO操作是否完成。
3. 异步IO(Asynchronous IO)
异步IO是一种更为高级的IO模式,它允许应用程序在发起IO请求后立即继续执行其他任务,而无需等待IO操作完成。与非阻塞IO不同,异步IO在IO操作完成时会通过回调函数通知应用程序。
以下是一个明了的异步IO示例代码:
c
#include
#include
#include
#include
#include
#include
int main() {
int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("Error opening file");
return 1;
}
struct epoll_event event;
event.data.fd = fd;
event.events = EPOLLIN;
int epoll_fd = epoll_create(1);
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event);
char ch;
while (read(fd, &ch, 1) > 0) {
putchar(ch);
}
close(fd);
close(epoll_fd);
return 0;
}
在这个示例中,程序会立即返回,并通过epoll机制等待IO事件。
4. IO多路复用(IO Multiplexing)
IO多路复用允许一个应用程序同时监控多个IO操作。在IO多路复用模式下,应用程序会向操作系统注册多个IO资源,并等待它们中的任何一个或多个变为就绪状态。当有IO操作就绪时,操作系统会通知应用程序。
以下是一个明了的IO多路复用示例代码:
c
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main() {
int epoll_fd = epoll_create(1);
if (epoll_fd == -1) {
perror("Error creating epoll file descriptor");
return 1;
}
int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("Error opening file");
return 1;
}
struct epoll_event event;
memset(&event, 0, sizeof(event));
event.events = EPOLLIN;
event.data.fd = fd;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event);
char ch;
while (1) {
int nfds = epoll_wait(epoll_fd, &event, 1, -1);
if (nfds == -1) {
perror("Error waiting for epoll