首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux poll 例子

poll 是 Linux 系统中用于 I/O 多路复用的一个系统调用,它允许单个进程/线程处理多个文件描述符的 I/O 事件。与 selectepoll 相比,poll 提供了更简洁的接口,并且在处理大量文件描述符时性能较好。

基础概念

poll 系统调用通过一个 pollfd 结构体数组来监视多个文件描述符。每个 pollfd 结构体包含以下字段:

  • fd:要监视的文件描述符。
  • events:感兴趣的事件,如读就绪(POLLIN)、写就绪(POLLOUT)等。
  • revents:实际发生的事件,由内核在调用返回时设置。

优势

  1. 简洁的接口:相比 selectpoll 的接口更简洁,不需要重新初始化文件描述符集合。
  2. 无文件描述符数量限制poll 没有像 select 那样的文件描述符数量限制。
  3. 更好的性能:在处理大量文件描述符时,poll 的性能优于 select

类型与应用场景

poll 主要用于需要同时监视多个文件描述符(如套接字、管道等)的场景,常见于网络服务器编程。

示例代码

以下是一个简单的 poll 使用示例,演示如何使用 poll 监听一个套接字的读事件:

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define MAX_EVENTS 10

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int addrlen = sizeof(address);

    // 创建套接字
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // 绑定套接字
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(8080);
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 监听连接
    if (listen(server_fd, 3) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    struct pollfd fds[MAX_EVENTS];
    fds[0].fd = server_fd;
    fds[0].events = POLLIN;

    while (1) {
        int ret = poll(fds, MAX_EVENTS, -1);
        if (ret < 0) {
            perror("poll");
            exit(EXIT_FAILURE);
        }

        for (int i = 0; i < MAX_EVENTS; i++) {
            if (fds[i].revents & POLLIN) {
                if (fds[i].fd == server_fd) {
                    // 接受新连接
                    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
                        perror("accept");
                        exit(EXIT_FAILURE);
                    }
                    fds[1].fd = new_socket;
                    fds[1].events = POLLIN;
                } else {
                    // 处理读事件
                    char buffer[1024] = {0};
                    read(fds[i].fd, buffer, 1024);
                    printf("Received message: %s\n", buffer);
                }
            }
        }
    }

    return 0;
}

可能遇到的问题及解决方法

  1. 文件描述符泄漏:确保在不再需要文件描述符时关闭它们,以避免资源泄漏。
  2. 文件描述符泄漏:确保在不再需要文件描述符时关闭它们,以避免资源泄漏。
  3. 处理多个并发连接:如果需要处理大量并发连接,可以考虑使用 epoll,它在处理大量文件描述符时性能更好。
  4. 超时处理:在调用 poll 时,可以设置超时时间,以避免无限期等待。
  5. 超时处理:在调用 poll 时,可以设置超时时间,以避免无限期等待。

通过以上示例和说明,你应该能够理解 poll 的基本用法及其在实际应用中的优势和使用场景。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Linux select poll源码剖析

在读select、poll源码前,需要先了解的知识点: 等待队列 文件系统(主要是进程的打开文件描述符表以及struct file) poll机制 资源注册监听poll() -> poll_wait(...select()/poll()调用对应一个struct poll_wqueues 一个监听事件对应一个struct poll_table_entry Common poll机制是所有多路转接的共性;调用控制块.../* * Structures and helpers for sys_poll/sys_poll */ struct poll_wqueues { poll_table pt; struct...实际linux内核设计: * 每个wait_queue_t的private字段指向同一个poll_wqueues,然后 * 共用的poll_wqueues中保存了指向调用进程...被封装在了poll_wqueues结构体中,以便之后向资源 * 注册监听的时候,能够用poll_table得到对应的poll_wqueues * * 初始化poll_wqueues

3.2K20
  • 【Linux】高级IO --- 多路转接,select,poll,epoll

    下面我们讲一个例子先来浅浅谈一下这5个模型IO的做法。...在上面的例子中,你认为谁的钓鱼方式更加高效呢?首先我们认为,如果一个人在不停的钓鱼,时不时的就收鱼竿,把鱼钓上来,等待鱼儿上钩的时间比重却很低,那么这个人在我看来他的钓鱼方式就是高效的。...而上面的例子中,鱼其实就是数据,鱼竿其实就是文件描述符fd,每个人都算是进程,但除了钱七的司机,这个司机算是操作系统,河流就是内核缓冲区,鱼漂就是就绪的事件,代表钓鱼这件事情已经就绪了,进程可以对数据做拷贝了...在这里额外补充一下,linux命令行中表示输入结束的快捷键是ctrl+d,当此热键被用户按下后,代表0号文件描述符写端关闭,此时读端会读到0,read会返回0值,此时进程除了输出提示信息"read file...虽然说epoll是作了改进的poll,但在接口的使用和底层实现上,epoll和poll天差地别,在linux内核2.5.44版本时,就引入了epoll接口,而现在主流的linux内核版本已经是3点几了。

    36330

    【Linux高级IO】Linux多路转接:深入探索poll与epoll的奥秘

    ❀ Linux高级IO 多路转接:poll poll函数接口 poll优缺点 多路转接:epoll epoll的相关系统调用 epoll工作原理 epoll的优点 epoll工作方式 理解ET模式和非阻塞文件描述符...为了应对这一挑战,Linux操作系统提供了多种I/O多路复用技术,其中poll和epoll作为两种重要的机制,在提升系统资源利用率和处理效率方面发挥着关键作用。...多路转接:poll 在Linux系统中,多路转接技术是一种重要的I/O处理机制,它允许单个线程同时监控多个文件描述符(例如套接字)上的事件,从而有效地管理多个并发连接。...在内核层面,遍历检测,关心的fd是否有对应的事件就绪 poll作为Linux中的多路转接技术之一,在处理多个并发连接时具有一定的优势。...多路转接:epoll epoll是Linux下多路复用I/O接口select/poll的增强版本,旨在提高程序在大量并发连接中只有少量活跃情况下的系统CPU利用率。

    11110

    大话 Select、Poll、Epoll

    遗憾的是,linux的网络IO中是不存在异步IO的,linux的网络IO处理的第二阶段总是阻塞等待数据copy完成的。真正意义上的网络异步IO是Windows下的IOCP(IO完成端口)模型。...2 Linux的socket 事件wakeup callback机制 言归正传,在介绍select、poll、epoll前,有必要说说linux(2.6+)内核的事件wakeup callback机制,...Linux通过socket睡眠队列来管理所有等待socket的某个事件的process,同时通过wakeup机制来异步唤醒整个睡眠队列上等待事件的process,通知process相关事件发生。...在linux 2.6.8之前的内核,epoll使用hash来组织fds集合,于是在创建epoll fd的时候,epoll需要初始化hash的大小。...在linux 2.6.8以后的内核中,epoll使用红黑树来组织监控的fds集合,于是epoll_create(int size)的参数size实际上已经没有意义了。

    26K4921

    select,poll,epoll区别

    select的一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,不过可以通过修改宏定义甚至重新编译内核的方式提升这一限制。...epoll 直到Linux2.6才出现了由内核直接支持的实现方法,那就是epoll,它几乎具备了之前所说的一切优点,被公认为Linux2.6下性能最好的多路I/O就绪通知方法。...实际上,当前版本的Linux会自动修改timeout参数,设置它的值为剩余时间。...不过 epoll则没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max...4.内核微调     这一点其实不算epoll的优点了,而是整个linux平台的优点。也许你可以怀疑linux平台,但是你无法回避linux平台赋予你微调内核的能力。

    1.4K21

    使用 poll 检测管道断开

    一般使用 poll 检测 socket 或标准输入时,只要指定 POLLIN 标志位,就可以检测是否有数据到达,或者连接断开: 1 struct pollfd fds[3]; 2 fds[0].fd...sock_fd; 5 fds[1].events = POLLIN; 6 fds[2].fd = pipe_fd; 7 fds[2].events = POLLIN; 8 ret = poll...一个已经关闭的句柄时(句柄号 >=0 有效),poll 本身并不返回错误,而是给对应的句柄事件中设置  POLLNVAL 标志位: 1 if (pfd[2].revents & POLLNVAL) {...2 // handle pipe close 3 ... 4 } 若 poll 一个无效句柄时(句柄号为-1),poll 本身仍不返回错误,但该句柄一定没有任何事件可供检测与返回...当然如果传入 poll 的句柄数组中所有句柄都为无效句柄时,poll仍不返回错误,此时若提供超时,可当成sleep使用; 若不提供超时,则会进入无限期等待…… 测试代码

    78720
    领券