
IO 多路复用(I/O Multiplexing)是一种允许一个进程同时处理多个网络连接的技术。它通过将多个IO请求合并为一个请求,然后一次性处理这些请求,从而提高系统的效率和响应速度。常见的IO多路复用技术包括 select、poll 和 epoll。
select 是最早的IO多路复用技术之一,广泛应用于各种操作系统中。select 函数可以监控多个文件描述符(FD),并返回其中已经准备好进行读写操作的文件描述符。select 可以同时监控读、写和异常三种类型的事件。select 都需要传递整个文件描述符集合,效率较低。#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
fd_set readfds;
struct timeval timeout;
int fd = open("test.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
timeout.tv_sec = 5;
timeout.tv_usec = 0;
int ret = select(fd + 1, &readfds, NULL, NULL, &timeout);
if (ret == -1) {
perror("select");
return 1;
} else if (ret == 0) {
printf("Timeout occurred! No data after 5 seconds.\n");
} else {
if (FD_ISSET(fd, &readfds)) {
char buffer[1024];
ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
if (bytes_read > 0) {
printf("Read %zd bytes: %s\n", bytes_read, buffer);
}
}
}
close(fd);
return 0;
}poll 是 select 的改进版本,解决了 select 的一些限制。poll 函数使用一个 pollfd 结构体数组来管理文件描述符及其感兴趣的事件。poll 可以监控更多的文件描述符,没有 select 的1024个文件描述符的限制。#include <stdio.h>
#include <poll.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
struct pollfd fds[1];
int fd = open("test.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
fds[0].fd = fd;
fds[0].events = POLLIN;
int ret = poll(fds, 1, 5000); // 超时时间为5000毫秒
if (ret == -1) {
perror("poll");
return 1;
} else if (ret == 0) {
printf("Timeout occurred! No data after 5 seconds.\n");
} else {
if (fds[0].revents & POLLIN) {
char buffer[1024];
ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
if (bytes_read > 0) {
printf("Read %zd bytes: %s\n", bytes_read, buffer);
}
}
}
close(fd);
return 0;
}epoll 是 Linux 特有的IO多路复用技术,性能优于 select 和 poll。epoll 使用三个系统调用:epoll_create、epoll_ctl 和 epoll_wait。epoll_create 创建一个 epoll 实例。epoll_ctl 注册或删除文件描述符及其感兴趣的事件。epoll_wait 等待文件描述符上的事件。#include <stdio.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int epoll_fd = epoll_create(10);
if (epoll_fd == -1) {
perror("epoll_create");
return 1;
}
int fd = open("test.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
perror("epoll_ctl");
return 1;
}
struct epoll_event events[10];
int num_events = epoll_wait(epoll_fd, events, 10, 5000); // 超时时间为5000毫秒
if (num_events == -1) {
perror("epoll_wait");
return 1;
} else if (num_events == 0) {
printf("Timeout occurred! No data after 5 seconds.\n");
} else {
for (int i = 0; i < num_events; i++) {
if (events[i].events & EPOLLIN) {
char buffer[1024];
ssize_t bytes_read = read(events[i].data.fd, buffer, sizeof(buffer));
if (bytes_read > 0) {
printf("Read %zd bytes: %s\n", bytes_read, buffer);
}
}
}
}
close(fd);
close(epoll_fd);
return 0;
}IO多路复用机制通过允许一个进程同时处理多个网络连接,提高了系统的效率和响应速度。select、poll 和 epoll 是常见的IO多路复用技术,各有优缺点。选择合适的IO多路复用技术取决于具体的应用场景和需求。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。