电子大神的日记本,供应链专家的功夫茶盘,在这里记录、分享与共鸣。

登录以开始

关于select函数中struct timeval问题★★★★★★

如果select调用中设置了等待时间,那么每次调用时都需要重新对这个时间赋值么?就像对fd_set处理一样。
例如:
fd_set readfd;
struct timval tv;
while(1) {
  FD_ZERO(&readfd);
  FD_SET(fd, &readfd);
  tv.tv_sec = 2;
  tv.tv_usec = 0;
  select(maxfd+1, &readfd, NULL, NULL, &tv);
  ......;
}
如上代码,对fd_set需要每次调用都要重新设置,那么对tv来说是否也是一样呢?能不能把对tv的赋值放在while外面?


之外意思就变了。


传的是一个引用进去,select里面可能会改变这个地址里保存的内容。所以每次循环都必须重新赋值


如楼主将时间的初始化放在外边,时间初始化为2秒,假设在1秒后发上了事件,则select将会返回并将tv的时间变成上次阻塞的剩余时间,即1秒,然后再进行监视套接字。这是因为linux系统对select()的实现中会修改参数tv为剩余时间。所以在循环内部使用函数select的时候一定要在循环内部初始化时间参数。

 

==================================================================

所以对于select函数中的最后一个参数,需要在循环中设置,每次循环要重新设置。如果设在循环外面,当循环执行起来后,每次循环select都会修改tv的值,tv的值越来越小,导致最后会产生select函数这tv时间内收不到有效时间,而返回-1,造成错误。

==================================================================

在网络程序中,一个进程同时处理多个文件描述符是很常见的情况。select()系统调用可以使进程检测同时等待的多个I/O设备,当没有设备准备好时,select()阻塞,其中任一设备准备好时,select()就返回。
    这个函数真是神通广大,用来定时也不错。
select(0, NULL, NULL, NULL, &tv); tv每次执行select前都要重新设定一遍,不然就变成0了。感觉它的精度比usleep()要高一些。

select()的调用形式为:
    #include
    #include
    int select(int maxfd, fd_set *readfds, fd_set *writefds, fe_set *exceptfds, const struct timeval *timeout);
    select的第一个参数是文件描述符集中要被检测的比特数,这个值必须至少比待检测的最大文件描述符大1;参数readfds指定了被读监控的文件描述符集;参数writefds指定了被写监控的文件描述符集;而参数exceptfds指定了被例外条件监控的文件描述符集。
    参数timeout起了定时器的作用:到了指定的时间,无论是否有设备准备好,都返回调用。timeval的结构定义如下:
    struct timeval{
        long tv_sec; //秒
        long tv_usec; //微秒
    }
    timeout取不同的值,该调用就表现不同的性质:
    timeout为0,调用立即返回;
    timeout为NULL,select()调用就阻塞,直到知道有文件描述符就绪;
    timeout为正整数,就是一般的定时器。
    select调用返回时,除了那些已经就绪的描述符外,select将清除readfds、writefds和exceptfds中的所有没有就绪的描述符。select的返回值有如下情况:
    正常情况下返回就绪的文件描述符个数;
    经过了timeout时长后仍无设备准备好,返回值为0;
    如果select被某个信号中断,它将返回-1并设置errno为EINTR。
    如果出错,返回-1并设置相应的errno。

博主
xuyaosong
积跬步
每天最重要的任务(Most Important Task)就是一天中你最需要完成的事情。为自己的每一天规定三件最重要的任务,而且是必须完成的。在这三件最重要的任务中,至少有一件任务是和我的生活目标相关的。而其他的两件事可以是工作上的事情(或是生活中的一些琐事)。学会每天设定三件最重要的任务,这将给我们的世界带来巨大的变化。如此,我们的每一天都朝着自己的人生目标前进,而且我们的生活也变得更充实。我们每天早晨醒来就为完成这三件最重要的任务而努力, 从而每天余暇的时间也就能更随心所欲地自己支配了。
点击跳转