• [apue] 使用 poll 检测管道断开


    一般使用 poll 检测 socket 或标准输入时,只要指定 POLLIN 标志位,就可以检测是否有数据到达,或者连接断开:

     1 struct pollfd fds[3];
     2 fds[0].fd = STDIN_FILENO;
     3 fds[0].events = POLLIN; 
     4 fds[1].fd = sock_fd; 
     5 fds[1].events = POLLIN; 
     6 fds[2].fd = pipe_fd; 
     7 fds[2].events = POLLIN; 
     8 ret = poll(fds, 3, -1);
     9 if (ret > 0) { 
    10     if (fds[0].revents & POLLIN) {
    11         // handle stdin
    12         ...
    13     }
    14     if (fds[1].revents & POLLIN) { 
    15         // handle socket input
    16         ...
    17     }
    18     if (fds[2].revents & POLLIN) { 
    19         // handle pipe input
    20         ...
    21     }        
    22 }

    当 read 结果返回 0 时表示相应连接断开。

    而对于 pipe,只检测POLLIN是感知不到管道断开的,当管道断开时,会在revents设置POLLHUP,必需额外检测此标志位:

    1 if (pfd[2].revents & POLLHUP) {
    2       // handle pipe break
    3       ...
    4 }

     而当 poll 一个已经关闭的句柄时(句柄号 >=0 有效),poll 本身并不返回错误,而是给对应的句柄事件中设置  POLLNVAL 标志位:

    1 if (pfd[2].revents & POLLNVAL) {
    2       // handle pipe close
    3       ...
    4 }

    若 poll 一个无效句柄时(句柄号为-1),poll 本身仍不返回错误,但该句柄一定没有任何事件可供检测与返回。因此可用于占位处理,

    例如固定从数组某个下标中取出某个句柄时可以在不相关位置设置-1句柄,这样就不用再去判断当前有事件的句柄的源句柄是哪一个了:

    1 struct pollfd fds[3];
    2 fds[0].fd = STDIN_FILENO;
    3 fds[0].events = POLLIN; 
    4 fds[1].fd = -1; 
    5 fds[1].events = POLLIN; 
    6 fds[2].fd = pipe_fd; 
    7 fds[2].events = POLLIN; 
    8 ret = poll(fds, 3, -1);
    9 ……

    例如当没有 socket  句柄时,该位置保持-1,这样可以不用将管道句柄上移,从而可以固定从fds[2]中取出管道句柄。

    当然如果传入 poll 的句柄数组中所有句柄都为无效句柄时,poll仍不返回错误,此时若提供超时,可当成sleep使用;

    若不提供超时,则会进入无限期等待……

    测试代码

  • 相关阅读:
    PAT A1097 Deduplication on a Linked List (25 分)——链表
    PAT A1115 Counting Nodes in a BST (30 分)——二叉搜索树,层序遍历或者dfs
    PAT A1113 Integer Set Partition (25 分)——排序题
    PAT A1112 Stucked Keyboard (20 分)——字符串
    PAT A1118 Birds in Forest (25 分)——并查集
    JAVA入门之程序设计环境搭建
    Win7命令终端基础配色指南
    泛微e-cology和Oracle无法启动的解决方案
    C指针和数组
    float类型与16进制的相互转换
  • 原文地址:https://www.cnblogs.com/goodcitizen/p/11007711.html
Copyright © 2020-2023  润新知