【问题标题】:Time remaining on a select() callselect() 调用的剩余时间
【发布时间】:2009-01-27 22:22:03
【问题描述】:

我在 Linux/ARM 平台上使用select() 来查看 udp 套接字是否收到了数据包。如果在超时之前返回(检测到数据包),我想知道 select 调用中还剩多少时间。

类似的东西:

int wait_fd(int fd, int msec)
{
    struct timeval tv;
    fd_set rws;

    tv.tv_sec = msec / 1000ul;
    tv.tv_usec = (msec % 1000ul) * 1000ul;

    FD_ZERO( & rws);
    FD_SET(fd, & rws);

    (void)select(fd + 1, & rws, NULL, NULL, & tv);

    if (FD_ISSET(fd, &rws)) { /* There is data */
        msec = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
        return(msec?msec:1);
    } else { /* There is no data */
        return(0);
    }
}

【问题讨论】:

  • 我不确定你的问题是什么。您的代码解决了问题;剩余时间写入超时参数。 Quoth select(2):“在 Linux 上,select() 修改超时以反映未睡眠的时间量;大多数其他实现不这样做。(POSIX.1-2001 允许任何一种行为。)”
  • @phihag: "允许任何一种行为"... 在 select 调用后精确查看超时值是不可移植的

标签: c linux select polling


【解决方案1】:

最安全的做法是忽略select() 的模糊定义并自己计时。

只需获取选择前后的时间,然后从您想要的时间间隔中减去。

【讨论】:

  • 我最终通过 gettimeofday() 函数调用前后做了这个。
【解决方案2】:

如果我没记错的话,select() 函数会处理超时和 I/O 参数,当 select 返回时,剩余时间会在超时变量中返回。

否则,您将不得不在调用之前记录当前时间,然后再次获取两者之间的差异。

【讨论】:

  • select() 的文档说,如果函数成功返回(不超时),超时值“可能”会改变。我想知道是否有一个简单的习惯用法或替代库调用来做到这一点。
  • 既然您正在为特定平台编写应用程序,为什么不尝试一下,看看在该平台上调用后超时值是否发生了变化。
  • 我刚刚重新阅读了 C 文档,我同意,超时的使用充其量是模棱两可的。正如亚当所说,您可以尝试一下并查看您的平台,否则这是我为您建议的 B 计划。
  • 在选择调用后查看超时是实现定义的。依赖于你的实现,充其量是不可移植的。
【解决方案3】:

来自 OSX 上的“人选”:

 Timeout is not changed by select(), and may be reused on subsequent calls, however it 
 is good style to re-ini-tialize it before each invocation of select().

您需要在调用 select 之前调用 gettimeofday,然后在退出时调用 gettimeofday。

[编辑] linux好像有点不一样:

   (ii)   The select function may update the timeout parameter to indicate
          how much time was left. The pselect  function  does  not  change
          this parameter.

   On Linux, the function select modifies timeout to reflect the amount of
   time not slept; most other implementations do not do this.  This causes
   problems  both  when  Linux code which reads timeout is ported to other
   operating systems, and when code is  ported  to  Linux  that  reuses  a
   struct  timeval  for  multiple selects in a loop without reinitializing
   it.  Consider timeout to be undefined after select returns.

【讨论】:

    【解决方案4】:

    Linux select() 更新超时参数以反映过去的时间。

    请注意,这不能跨其他系统移植(因此上面引用的 OS X 手册中的警告)但适用于 Linux。

    吉拉德

    【讨论】:

      【解决方案5】:

      不要使用 select,在你的代码中尝试使用大于 1024 的 fd,看看你会得到什么。

      【讨论】:

        猜你喜欢
        • 2014-11-04
        • 1970-01-01
        • 2018-02-03
        • 2018-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-05
        • 1970-01-01
        相关资源
        最近更新 更多