如何在sys/select.h中正确使用

How to correctly use in sys/select.h

在以下代码中使用计时器时,要么出现"Error calling select"错误,要么出现新数据:

    timeval tv;
    tv.tv_sec = 1;
    tv.tv_usec = 0;
    if( select(s + 1, &readmask, NULL, NULL, &tv ) <= 0 )
    {
         perror("Error calling select");
         return 0;
    }

在不中断会话的情况下,可以在客户端上做些什么来避免在您重新访问此代码时出现此错误?

您不应该使用 <= 0 作为条件,因为 0 表示超时,< 0 表示错误。

选择:

if(int rv = select(s + 1, &readmask, NULL, NULL, &tv ); rv > 0) {
    // success
} else if(rv == 0) {
    // timeout
} else {
    // error
}

What can be done on the client without breaking the session in order to avoid this error when you re-access this code?

如果您在将代码更改为上述代码后过快地收到 timeouts,您应该仔细查看 timeout 参数。您应该在每次调用 select:

之前重新初始化它

"On Linux, select() modifies timeout to reflect the amount of time not slept; most other implementations do not do this. (POSIX.1 permits either behavior.) 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 select()s in a loop without reinitializing it. Consider timeout to be undefined after select() returns."

...

"On Linux, select() also modifies timeout if the call is interrupted by a signal handler (i.e., the EINTR error return). This is not permitted by POSIX.1."