当前位置: 首页 > news >正文

Linux学习笔记--POLL_SELECT方式读取输入数据

头文件和变量

#include <poll.h>      // poll 系统调用struct pollfd fds[1];  // poll 文件描述符数组
nfds_t nfds = 1;       // 要监视的文件描述符数量

poll 的工作原理

poll 允许程序同时监视多个文件描述符,等待其中任何一个变为可读、可写或有异常条件。

核心思想
  • 避免忙等待:进程不需要主动轮询每个文件描述符

  • 事件驱动:内核在事件发生时通知应用程序

  • 批量监视:一次系统调用可以监视多个文件描述符

#include <poll.h>struct pollfd {int   fd;        /* 文件描述符 */short events;    /* 请求监视的事件 */short revents;   /* 实际发生的事件 */
};int poll(struct pollfd *fds, nfds_t nfds, int timeout);
应用程序设置监视参数
struct pollfd fds[2];
fds[0].fd = fd1;           // 第一个文件描述符
fds[0].events = POLLIN;    // 监视可读事件
fds[0].revents = 0;        // 初始化为0fds[1].fd = fd2;           // 第二个文件描述符  
fds[1].events = POLLIN | POLLOUT;  // 监视可读和可写事件
fds[1].revents = 0;int ret = poll(fds, 2, 5000);  // 监视2个fd,超时5秒
内核内部处理

当应用程序调用 poll() 时:

        注册监视:内核将应用程序要监视的文件描述符和事件类型记录下来

        进程挂起:调用进程被放入等待队列,进入睡眠状态

        内核监视:内核持续监视所有注册的文件描述符

  1. 事件触发:当任何被监视的文件描述符就绪时,内核:

    • 设置对应的 revents 字段

    • 唤醒等待的进程

  2. 超时处理:如果指定的超时时间到达,内核也会唤醒进程

事件类型

常用的事件标志:

  • POLLIN:数据可读

  • POLLOUT:可写入数据

  • POLLERR:发生错误

  • POLLHUP:连接挂起

  • POLLNVAL:文件描述符未打开

poll 与其他 I/O 多路复用技术的对比

1. 与 select 的比较

select 的缺点:

  • 文件描述符数量有限(通常 1024)

  • 每次调用需要重置 fd_set

  • 效率随 fd 数量增加而下降

poll 的优点:

  • 无文件描述符数量限制

  • 更清晰的接口

  • 更好的性能

2. 与 epoll 的比较

epoll 的优势:

  • 更高效的处理大量文件描述符

  • 边缘触发模式

  • 不需要每次重新注册

while (1)
{// 设置 poll 监视参数fds[0].fd = fd;          // 要监视的文件描述符fds[0].events  = POLLIN; // 监视可读事件fds[0].revents = 0;      // 实际发生的事件(由内核填充)// 调用 poll,超时时间 5000ms (5秒)ret = poll(fds, nfds, 5000);if (ret > 0)        // 有事件发生{if (fds[0].revents == POLLIN)  // 输入设备有数据可读{// 读取所有可用事件(非阻塞)while (read(fd, &event, sizeof(event)) == sizeof(event)){printf("get event: type = 0x%x, code = 0x%x, value = 0x%x\n", event.type, event.code, event.value);}}}else if (ret == 0)  // 超时{printf("time out\n");}else                // 错误{printf("poll err\n");}
}

poll 调用参数

ret = poll(fds, nfds, 5000);
  • fds: 指向 pollfd 结构体数组的指针

  • nfds: 监视的文件描述符数量(这里是 1)

  • 5000: 超时时间(毫秒),5秒后如果没有事件则返回

poll 返回值处理

情况 1: ret > 0 - 有事件发生
if (fds[0].revents == POLLIN)
{while (read(fd, &event, sizeof(event)) == sizeof(event)){// 处理每个事件}
}
  • 检查 revents 字段确认是读取事件

  • 使用 while 循环读取所有可用事件(因为设备以非阻塞模式打开)

  • 当 read 返回 -1 且 errno 为 EAGAIN 时,表示没有更多数据

情况 2: ret == 0 - 超时
printf("time out\n");
情况 3: ret < 0 - 错误
printf("poll err\n");

poll 系统调用出错。

使用示例

# 编译
gcc -o input_monitor input_monitor.c# 运行(监控键盘事件)
sudo ./input_monitor /dev/input/event1

输出

bustype = 0x3
vendor  = 0x46d
product = 0xc52b
version = 0x111
support ev type: EV_SYN EV_KEY EV_MSC EV_LED get event: type = 0x1, code = 0x1c, value = 0x1  # 回车键按下
get event: type = 0x0, code = 0x0, value = 0x0    # 同步事件
get event: type = 0x1, code = 0x1c, value = 0x0   # 回车键释放
get event: type = 0x0, code = 0x0, value = 0x0    # 同步事件
time out  # 5秒内无事件
time out  # 再过5秒无事件
get event: type = 0x1, code = 0x2, value = 0x1    # 数字1键按下
...

poll其他应用场景

1. 网络服务器
// 同时监视监听socket和所有客户端连接
struct pollfd fds[MAX_CLIENTS + 1];
fds[0].fd = listen_sock;
fds[0].events = POLLIN;// 添加客户端连接
for (int i = 1; i <= client_count; i++) {fds[i].fd = client_sockets[i-1];fds[i].events = POLLIN;
}
2. 多输入源应用
// 同时监视键盘、鼠标、网络等多个输入
struct pollfd fds[3];
fds[0].fd = keyboard_fd;    // 键盘设备
fds[1].fd = mouse_fd;       // 鼠标设备  
fds[2].fd = network_fd;     // 网络套接字
3. 超时处理
// 实现带超时的操作
ret = poll(&fds, 1, 1000);  // 等待1秒
if (ret == 0) {// 超时处理handle_timeout();
}

http://www.dtcms.com/a/467274.html

相关文章:

  • STM32项目分享:基于智能电扇的设计与实现
  • 大兴智能网站建设哪家好陕西宁德建设工程有限公司网站
  • 没有网站可以域名备案吗wordpress安装后只有英文
  • 网站和网页的设计方法南翔做网站公司
  • 外贸网络推广价格seo值是什么意思
  • 简单商业网站模板找网站公司制作网站
  • Unity Mask镂空效果(常用于新手引导或高亮显示UI元素)
  • 网站名是什么免费视频网站大全
  • Unity实现圆柱螺旋曲线运动方程
  • wordpress企业建长沙关键词优化新报价
  • 学习爬虫第五天:自动化爬虫
  • 专业的网站建设制作服务wordpress注册字段
  • 有关网站备案号规则怎么设计网站规划方案
  • 兰州网站建设推荐q479185700顶你做阀门网站电话
  • 怎么制作微信购物网站怎么开发手机app
  • 广州翼讯资讯科技有限公司 网站wordpress更换主题白屏
  • php网站开发模式有哪些网页设计与网站建设的概述
  • 网站风格细节dede增加手机网站
  • 中国数据安全保护法介绍与实践案例
  • 龙虎榜——20251010
  • 东莞建域名网站服装网站建设定制
  • 数据结构------二叉查找树
  • 电子商务网站商品怎么来制作ppt用什么软件
  • 网站官网认证加v怎么做江苏网络推广排名
  • 《jEasyUI 创建页脚摘要》
  • 设计网站的管理系统宁波网络营销推广咨询报价
  • 优秀的移动端网站合肥快速建站在线咨询
  • 网站建设要哪些seo济南手机网站建设公司报价
  • 企业网站不足云主机免费申请
  • 合肥市庐阳区住房和城乡建设局网站深圳品牌设计公司深圳品牌设计公司