首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >IO 模型——IO 多路复用机制?

IO 模型——IO 多路复用机制?

原创
作者头像
代码小李
发布2024-12-30 15:35:34
发布2024-12-30 15:35:34
3880
举报

IO 多路复用机制

IO 多路复用(I/O Multiplexing)是一种允许一个进程同时处理多个网络连接的技术。它通过将多个IO请求合并为一个请求,然后一次性处理这些请求,从而提高系统的效率和响应速度。常见的IO多路复用技术包括 selectpollepoll

1. select
  • 描述select 是最早的IO多路复用技术之一,广泛应用于各种操作系统中。
  • 使用方法
    • select 函数可以监控多个文件描述符(FD),并返回其中已经准备好进行读写操作的文件描述符。
    • select 可以同时监控读、写和异常三种类型的事件。
  • 优点
    • 简单易用,跨平台性好。
  • 缺点
    • 最大支持的文件描述符数量有限(通常是1024)。
    • 每次调用 select 都需要传递整个文件描述符集合,效率较低。
    • 返回时需要重新遍历所有文件描述符集合,查找哪些文件描述符已经准备好。
代码语言:txt
复制
#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;
}
2. poll
  • 描述pollselect 的改进版本,解决了 select 的一些限制。
  • 使用方法
    • poll 函数使用一个 pollfd 结构体数组来管理文件描述符及其感兴趣的事件。
    • poll 可以监控更多的文件描述符,没有 select 的1024个文件描述符的限制。
  • 优点
    • 支持更多的文件描述符。
    • 不需要重新初始化文件描述符集合。
  • 缺点
    • 仍然需要遍历所有文件描述符集合,查找哪些文件描述符已经准备好。
代码语言:txt
复制
#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;
}
3. epoll
  • 描述epoll 是 Linux 特有的IO多路复用技术,性能优于 selectpoll
  • 使用方法
    • epoll 使用三个系统调用:epoll_createepoll_ctlepoll_wait
    • epoll_create 创建一个 epoll 实例。
    • epoll_ctl 注册或删除文件描述符及其感兴趣的事件。
    • epoll_wait 等待文件描述符上的事件。
  • 优点
    • 支持更多的文件描述符。
    • 高效的事件通知机制,不需要遍历所有文件描述符集合。
    • 支持边缘触发和水平触发两种模式。
  • 缺点
    • 仅限于 Linux 系统。
代码语言:txt
复制
#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多路复用机制通过允许一个进程同时处理多个网络连接,提高了系统的效率和响应速度。selectpollepoll 是常见的IO多路复用技术,各有优缺点。选择合适的IO多路复用技术取决于具体的应用场景和需求。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • IO 多路复用机制
    • 1. select
    • 2. poll
    • 3. epoll
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档