select() on a pipe in blocking mode returns EAGAIN

2019-07-17 17:30发布

The man pages for select() do not list EAGAIN as possible error code for the select() function.

Can anyone explain in which cases the select() can produce EAGAIN error?

If I understand select_tut man page, EAGAIN can be produced by sending a signal to the process which is blocked waiting on blocked select(). Is this correct?

Since I am using select() in blocking mode with timeout, like this:

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 ) );
}

should I just repeat the loop when the error number is EAGAIN?

2条回答
对你真心纯属浪费
2楼-- · 2019-07-17 17:36

select() will not return EAGAIN under any circumstance. It may, however, return EINTR if interrupted by a signal (This applies to most system calls).

EAGAIN (or EWOULDBLOCK) may be returned from read, write, recv, send, etc.

查看更多
迷人小祖宗
3楼-- · 2019-07-17 17:44

EAGAIN is technically not an error, but an indication that the operation terminated without completing, and you should...er...try it again. You will probably want to write logic to retry, but not infinitely. If that was safe, they would have done it themselves in the API.

If you are thinking that returing a silly non-error error code like that is kinda bad client interface design, you aren't the first. It turns out EAGAIN as an error code has a long interesting history in Unix. Among other things, it spawned the widely circulated essay on software design The Rise of Worse-is-Better. There's a couple of paragraphs in the middle that explain why Unix needs to return this sometimes. Yes, it does indeed have something to do with receiving interrupts during an I/O. They call it PC loser-ing.

Many credit this essay as one of the inspirations for Agile programming.

查看更多
登录 后发表回答