代码之家  ›  专栏  ›  技术社区  ›  BЈовић

阻塞模式下管道上的select()返回EAGAIN

  •  2
  • BЈовић  · 技术社区  · 14 年前

    这个 man pages for select() 不要将EAGAIN列为select()函数的可能错误代码。

    有人能解释一下select()在哪些情况下会产生EAGAIN错误吗?

    如果我明白 select_tut man page ,EAGAIN可以通过向进程发送一个信号来生成,该进程在等待blocked select()时被阻塞。这是对的吗?

    因为我在带超时的阻塞模式下使用select(),如下所示:

    bool selectRepeat = true;
    int res = 0;
    timeval  selectTimeout( timeout );
    while ( true == selectRepeat )
    {
      res = ::select( fd.Get() + 1,
                      NULL,
                      &writeFdSet,
                      NULL,
                      &selectTimeout );
      selectRepeat = ( ( -1 == res ) && ( EINTR == errno ) );
    }
    

    当错误号是EAGAIN时,我应该重复循环吗?

    2 回复  |  直到 14 年前
        1
  •  5
  •   Hasturkun    14 年前

    select() 不会再回来了 EAGAIN 在任何情况下。 但是,它可能会回来 EINTR 如果被信号中断(这适用于大多数系统调用)。

    伊根 (或 EWOULDBLOCK )可以从 read , write , recv , send 等等。

        2
  •  1
  •   T.E.D.    14 年前

    从技术上讲,EAGAIN不是一个错误,而是一个指示,表明操作在未完成的情况下终止,您应该…呃…再试一次。您可能需要编写逻辑来重试,但不能无限次。如果这是安全的,他们会在API中自己完成。

    如果你认为重复这样一个愚蠢的无错误代码是有点糟糕的客户端接口设计,你不是第一个。原来EAGAIN作为一个错误代码在Unix中有着很长的历史。除此之外,它还催生了一篇广为流传的关于软件设计的文章 The Rise of Worse-is-Better . 中间有几个段落解释了为什么Unix有时需要返回这个值。是的,这确实与I/O期间接收中断有关。他们称之为PC失败。

    许多人认为这篇文章是对敏捷编程的启示之一。