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

时间:2010-11-16 10:14:51

标签: c++ c linux select blocking

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

任何人都可以解释select()在哪些情况下会产生EAGAIN错误?

如果我理解select_tut man page,可以通过向进程发送信号来生成EAGAIN,该进程被阻塞等待阻塞的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 个答案:

答案 0 :(得分:4)

在任何情况下,

select()都不会返回EAGAIN。 但是,如果被信号中断,它可能会返回EINTR(这适用于大多数系统调用)。

EAGAIN(或EWOULDBLOCK)可能会从readwriterecvsend等返回。

答案 1 :(得分:1)

EAGAIN在技术上不是错误,而是指示操作在没有完成的情况下终止,你应该......呃......再试一次。您可能希望编写逻辑来重试,但不是无限的。如果这是安全的,他们会在API中自己完成。

如果您认为撤回一个愚蠢的非错误错误代码就像是一个糟糕的客户端界面设计,那么您不是第一个。事实证明,EAGAIN是一个错误代码,在Unix中有很长的历史。除此之外,它催生了广为流传的关于软件设计的论文The Rise of Worse-is-Better。中间有几个段落解释了为什么Unix有时需要返回它。是的,它确实与在I / O期间接收中断有关。他们称之为PC失败者。

许多人认为这篇文章是敏捷编程的灵感之一。