计算机的IO调用过程可以分为两个阶段:
IO调用 :应用程序进程向操作系统内核发起IO请求。IO执行:
操作系统内核完成IO操作,包括数据准备和数据拷贝两个过程。
具体步骤如下:
应用程序发起IO请求
应用程序通过系统调用(如`read()`、`write()`等)向操作系统请求进行IO操作。这些系统调用会触发一个IO请求,并等待操作系统处理。
操作系统准备数据
操作系统在接收到IO请求后,会进行数据准备。对于磁盘IO,操作系统会使用DMA(直接内存访问)技术将数据从磁盘读入内核缓冲区。对于网络IO,数据会从网卡加载到内核缓冲区。
数据拷贝
操作系统将数据从内核缓冲区拷贝到用户进程缓冲区。对于读操作,数据从内核缓冲区拷贝到用户进程的缓冲区,以便应用程序进行后续处理。对于写操作,数据从用户进程缓冲区拷贝到内核缓冲区,然后写入设备。
完成IO操作
一旦数据拷贝完成,操作系统会通知应用程序IO操作已完成。应用程序可以继续执行后续的指令。
同步与异步IO
同步IO:
在同步IO模型中,应用程序发起IO请求后,线程会阻塞等待,直到IO操作完成。
异步IO:在异步IO模型中,应用程序发起IO请求后,线程不会阻塞,而是通过回调函数或事件通知来处理IO操作的结果。异步IO通常使用IO多路复用技术(如select、poll、epoll)来提高性能。
程序查询方式和程序中断方式
程序查询方式:CPU不断查询I/O设备状态,直到设备准备就绪。这种方式下,CPU在信息传送过程中要花费很多时间来查询和等待,效率较低。
程序中断方式:中断是现代计算机有效合理地发挥效能和提高效率的一个重要功能。当I/O设备准备好后,会向CPU发送中断信号,CPU在处理完中断后会继续执行后续的IO操作。
示例代码
```c
include include include int main() { int fd; char buffer; // 打开文件 fd = open("test.txt", O_RDONLY); if (fd == -1) { perror("open"); return 1; } // 读取文件内容 while (read(fd, buffer, sizeof(buffer) - 1) != 0) { buffer[read(fd, buffer, sizeof(buffer) - 1)] = '\0'; printf("%s", buffer); } // 关闭文件 close(fd); return 0; } ``` 在这个示例中,应用程序通过`open()`系统调用打开文件,然后通过`read()`系统调用读取文件内容,直到文件末尾。整个过程是同步阻塞的,即应用程序在`read()`调用期间会等待数据从文件读取到内存中。