当前位置:实例文章 » 其他实例» [文章]31. IO操作

31. IO操作

发布人:shili8 发布时间:2025-01-13 14:49 阅读次数:0

**IO操作**

IO(Input/Output)操作是计算机程序中非常重要的一部分,它负责处理数据的输入和输出。IO操作可以分为两大类:同步IO和异步IO。

###1. 同步IO同步IO是最常见的IO类型,程序在进行IO操作时会阻塞等待IO完成,这意味着如果IO操作需要花费很长时间,整个程序都会被挂起。同步IO通常使用以下函数:

* `read()`:从文件或网络中读取数据* `write()`:向文件或网络中写入数据**示例代码**

c#include <stdio.h>
#include <stdlib.h>

int main() {
 // 打开一个文件 FILE *fp = fopen("example.txt", "r");
 if (fp == NULL) {
 printf("无法打开文件
");
 return1;
 }
 char buffer[1024];
 // 从文件中读取数据 while (fgets(buffer, sizeof(buffer), fp) != NULL) {
 printf("%s", buffer);
 }
 fclose(fp);
 return0;
}


###2. 异步IO异步IO是指程序在进行IO操作时不会阻塞等待IO完成,而是继续执行其他任务。当IO完成后,程序会被通知来处理结果。异步IO通常使用以下函数:

* `aio_read()`:从文件或网络中读取数据* `aio_write()`:向文件或网络中写入数据**示例代码**

c#include <stdio.h>
#include <stdlib.h>
#include <aio.h>

int main() {
 // 打开一个文件 int fd = open("example.txt", O_RDONLY);
 if (fd == -1) {
 printf("无法打开文件
");
 return1;
 }
 struct aiocb *iocb = malloc(sizeof(struct aiocb));
 iocb->aio_fildes = fd;
 iocb->aio_offset =0;
 iocb->aio_buf = malloc(1024);
 iocb->aio_nbytes =1024;
 iocb->aio_reqprio =0;
 // 开始异步读取 if (aio_read(iocb) == -1) {
 printf("无法开始读取
");
 free(iocb->aio_buf);
 close(fd);
 return1;
 }
 // 等待IO完成 aio_wait(NULL, iocb, NULL);
 char *data = iocb->aio_buf;
 // 处理读取的数据 printf("%s", data);
 free(iocb->aio_buf);
 close(fd);
 return0;
}


###3. IO多路复用IO多路复用是指在一个线程中同时处理多个IO操作,提高了程序的并发性和效率。常用的IO多路复用函数有:

* `select()`:等待一组文件描述符中的任何一个就绪* `poll()`:等待一组文件描述符中的任何一个就绪* `epoll_create()`:创建一个 epoll 对象**示例代码**

c#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>

int main() {
 // 打开两个文件 int fd1 = open("example1.txt", O_RDONLY);
 int fd2 = open("example2.txt", O_RDONLY);
 if (fd1 == -1 || fd2 == -1) {
 printf("无法打开文件
");
 return1;
 }
 // 等待一组文件描述符中的任何一个就绪 fd_set read_fds;
 FD_ZERO(&read_fds);
 FD_SET(fd1, &read_fds);
 FD_SET(fd2, &read_fds);
 struct timeval timeout;
 timeout.tv_sec =5;
 timeout.tv_usec =0;
 if (select(fd2 +1, &read_fds, NULL, NULL, &timeout) == -1) {
 printf("无法等待文件描述符就绪
");
 close(fd1);
 close(fd2);
 return1;
 }
 // 处理读取的数据 if (FD_ISSET(fd1, &read_fds)) {
 char buffer[1024];
 read(fd1, buffer, sizeof(buffer));
 printf("%s", buffer);
 }
 if (FD_ISSET(fd2, &read_fds)) {
 char buffer[1024];
 read(fd2, buffer, sizeof(buffer));
 printf("%s", buffer);
 }
 close(fd1);
 close(fd2);
 return0;
}


###4. IO复用IO复用是指在一个线程中同时处理多个IO操作,提高了程序的并发性和效率。常用的IO复用函数有:

* `epoll_create()`:创建一个 epoll 对象* `epoll_ctl()`:添加或删除一个文件描述符到 epoll 中**示例代码**

c#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>

int main() {
 // 打开两个文件 int fd1 = open("example1.txt", O_RDONLY);
 int fd2 = open("example2.txt", O_RDONLY);
 if (fd1 == -1 || fd2 == -1) {
 printf("无法打开文件
");
 return1;
 }
 // 创建一个 epoll 对象 int epfd = epoll_create(10);
 if (epfd == -1) {
 printf("无法创建 epoll 对象
");
 close(fd1);
 close(fd2);
 return1;
 }
 struct epoll_event event;
 // 添加文件描述符到 epoll 中 event.events = EPOLLIN;
 event.data.fd = fd1;
 if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd1, &event) == -1) {
 printf("无法添加文件描述符到 epoll 中
");
 close(fd1);
 close(fd2);
 return1;
 }
 event.events = EPOLLIN;
 event.data.fd = fd2;
 if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd2, &event) == -1) {
 printf("无法添加文件描述符到 epoll 中
");
 close(fd1);
 close(fd2);
 return1;
 }
 // 等待一组文件描述符中的任何一个就绪 struct epoll_event events[10];
 int num = epoll_wait(epfd, events,10, -1);
 if (num == -1) {
 printf("无法等待文件描述符就绪
");
 close(fd1);
 close(fd2);
 return1;
 }
 // 处理读取的数据 for (int i =0; i < num; i++) {
 if (events[i].events & EPOLLIN) {
 char buffer[1024];
 read(events[i].data.fd, buffer, sizeof(buffer));
 printf("%s", buffer);
 }
 }
 close(fd1);
 close(fd2);
 return0;
}


### 总结本文介绍了IO操作的基本概念和常用函数,包括同步IO、异步IO、IO多路复用和IO复用。通过示例代码,可以看到这些函数如何在实际应用中使用。

相关标签:python开发语言
其他信息

其他资源

Top