• Linux 命令 poll 和 ppoll 详解 + 实例



     🎈 作者:Linux猿

    🎈 简介:CSDN博客专家🏆,华为云享专家🏆,Linux、C/C++、云计算、物联网、面试、刷题、算法尽管咨询我,关注我,有问题私聊!

    🎈 关注专栏: 数据结构和算法成神路【精讲】优质好文持续更新中……🚀🚀🚀

    🎈 欢迎小伙伴们点赞👍、收藏⭐、留言💬


    本文主要对 Linux 命令 poll 和 ppoll 命令进行详细讲解,最后会以实例的方式进行说明,下面一起来看下吧!

    一、基本概念

    poll 和 ppoll 可以同时监听多个文件描述符上的事件,poll 函数和 ppoll 函数之间的关系类似于 select 和 pselect。

    二、poll 和 ppoll 函数

    2.1 poll 函数

    头文件:

    #include 

    声明:

    int poll(struct pollfd *fds, nfds_t nfds, int timeout);

    其中,各参数为:

    (1)struct pollfd *fds

      该参数是待监控事件的集合,struct pollfd 结构如下所示:

    1. struct pollfd {
    2. int fd; //文件描述符
    3. short events; //需求的事件类型
    4. short revents;//返回的事件类型
    5. };

    字段 fd 包含打开文件的文件描述符。如果为负数,则忽略相应的时间字段,并返回 0,。如果此字段指定为零,则 fd 的所有事件都将被忽略,并且 revents 返回 0。

    其中,events 和 revents 事件类型有如下种类:

    #define POLLIN            0x0001 //有数据需要读取
    #define POLLPRI          0x0002 //
    #define POLLOUT        0x0004 //可以写入数据
    #define POLLERR        0x0008 //调用出错,仅在revents中出现
    #define POLLHUP        0x0010 //调用中断,仅在revents中出现
    #define POLLNVAL       0x0020 //无效的请求,仅在revents中出现

    (2)nfds_t nfds

      监听事件的个数,表示 fds 数组的长度。

    (3)int timeout

    阻塞时间,单位是毫秒,函数调用一直等待,直到发生下列三种情况之一:

    • 有事件发生;
    • 等待超时;
    • 调用被中断;

    2.2 ppoll 函数

    poll 函数和 ppoll 函数之间的关系类似于 select 和 pselect。

    头文件:

    1. #define _GNU_SOURCE
    2. #include
    3. #include

    函数声明:

     int ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigmask);

    函数执行成功返回正数,表示发生事件的描述符的数量;如果返回值为 0,表示调用超时,且没有文件描述符就绪;如果返回 -1,表示出错。 

    三、实例

    下面来看下实例,如下所示:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
    8. int main(int argc, char *argv[])
    9. {
    10. int nfds, num_open_fds;
    11. struct pollfd *pfds;
    12. if (argc < 2)
    13. {
    14. fprintf(stderr, "Usage: %s file...\n", argv[0]);
    15. exit(EXIT_FAILURE);
    16. }
    17. num_open_fds = nfds = argc - 1;
    18. pfds = calloc(nfds, sizeof(struct pollfd));
    19. if (pfds == NULL)
    20. errExit("malloc");
    21. /* Open each file on command line, and add it 'pfds' array. */
    22. for (int j = 0; j < nfds; j++)
    23. {
    24. pfds[j].fd = open(argv[j + 1], O_RDONLY);
    25. if (pfds[j].fd == -1)
    26. errExit("open");
    27. printf("Opened \"%s\" on fd %d\n", argv[j + 1], pfds[j].fd);
    28. pfds[j].events = POLLIN;
    29. }
    30. /* Keep calling poll() as long as at least one file descriptor is
    31. open. */
    32. while (num_open_fds > 0)
    33. {
    34. int ready;
    35. printf("About to poll()\n");
    36. ready = poll(pfds, nfds, -1);
    37. if (ready == -1)
    38. errExit("poll");
    39. printf("Ready: %d\n", ready);
    40. /* Deal with array returned by poll(). */
    41. for (int j = 0; j < nfds; j++)
    42. {
    43. char buf[10];
    44. if (pfds[j].revents != 0)
    45. {
    46. printf(" fd=%d; events: %s%s%s\n", pfds[j].fd,
    47. (pfds[j].revents & POLLIN) ? "POLLIN " : "",
    48. (pfds[j].revents & POLLHUP) ? "POLLHUP " : "",
    49. (pfds[j].revents & POLLERR) ? "POLLERR " : "");
    50. if (pfds[j].revents & POLLIN)
    51. {
    52. ssize_t s = read(pfds[j].fd, buf, sizeof(buf));
    53. if (s == -1)
    54. errExit("read");
    55. printf(" read %zd bytes: %.*s\n",
    56. s, (int)s, buf);
    57. }
    58. else
    59. { /* POLLERR | POLLHUP */
    60. printf(" closing fd %d\n", pfds[j].fd);
    61. if (close(pfds[j].fd) == -1)
    62. errExit("close");
    63. num_open_fds--;
    64. }
    65. }
    66. }
    67. }
    68. printf("All file descriptors closed; bye\n");
    69. exit(EXIT_SUCCESS);
    70. }

    编译程序:

    gcc -o main main.c

    🎈CSDN博客专家🏆,华为云享专家🏆,Linux、C/C++、云计算、物联网、面试、刷题、算法尽管咨询我,关注我,有问题私聊!

    🎈 感觉有帮助记得「一键三连支持下哦!有问题可在评论区留言💬,感谢大家的一路支持!🤞猿哥将持续输出「优质文章回馈大家!🤞🌹🌹🌹🌹🌹🌹🤞


  • 相关阅读:
    JDBC API详解
    app运营:提高用户活跃度的技巧
    为什么需要在微服务中使用链路追踪?Spring Cloud 可以选择哪些微服务链路追踪方案?
    安装好tomcat后,启动tomcat点击 startup.bat 窗口一闪而过怎么解决
    YOLOv10改进教程|C2f-CIB加入注意力机制
    2021-01-01 - Review代码过程感悟
    一个Springboot配置顺序问题,让我直接回滚代码了
    计算机毕业设计之流浪宠物管理系统
    vue2-org-tree 树型结构的使用
    Vue3最佳实践 第六章 Pinia,Vuex与axios,VueUse 1(Pinia)
  • 原文地址:https://blog.csdn.net/u011074149/article/details/127137161