select()函数异常排查:仅首次调用有延迟后续无延迟问题
为什么只有第一次
select()调用会休眠1秒? 这是因为你忽略了select()系统调用对struct timeval参数的一个关键行为:它是一个传入传出参数。
当你第一次调用select(0, NULL, NULL, NULL, &tv)时,内核会从你设置的1秒开始倒计时,等时间到了之后,它会把tv里的值修改为剩余的未休眠时间——这里刚好休眠满1秒,剩余时间就是0秒0微秒。
而你的代码在循环里没有每次重置tv的值,后续调用select()时,传入的tv已经是tv_sec=0、tv_usec=0了。根据select()的规则,当超时时间设为0时,它会立即返回,不会有任何延迟。
怎么修复这个问题?
很简单,每次进入循环时重新初始化tv的值就行:
#include <stdio.h> #include <stdlib.h> int main() { for (;;) { struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; /* Sleep for one second */ int result=select(0, NULL, NULL, NULL, &tv); printf("select returned: %d\n",result); } }
或者在每次调用select()之后手动重置tv的值,效果是一样的。
另外补充一点:如果select()是因为某个文件描述符就绪而提前返回(不过你的代码里没有传入任何文件描述符,所以不会出现这种情况),tv同样会被设置为剩余的时间,这也是这个参数设计成传入传出的原因——让你知道还剩多少时间没等完。
内容的提问来源于stack exchange,提问作者Michael Goldshteyn
相关产品推荐
相关产品推荐

