关于select函数修改自身参数的问题

来源:互联网 发布:淘宝订单数据库表设计 编辑:程序博客网 时间:2024/06/06 01:00

我们在写socket编程的时候,如果采用非阻塞的方式,往往会用到select函数:

int select( int maxfd, fd_set *preadfds,fd_set *pwritefds,fd_set *perrorfds,struct timeval *ptimeout);

一般这样用:

    ……

   fd_set readfds;

   struct timeval timeout={1,0}//1秒超时

   ……

while1

{

  FD_ZERO(&readfds);

  FD_SET(sock,&readfds);

  ret = select(socket+1,&readfds,NULL,NULL,&timeout);

  if(ret>0)

{

    if(FD_ISSET(sock,&readfds))

{

recvfrom(socket,buffer,len,…);

……

}

}

……

}

以上是linux平台的select的用法,windows平台也类似,不过第一个参数maxfds可以随便填。这两个平台这样使用都没问题。但是笔者在td手机上,即大唐平台上应用,发现会死机(严格来讲,就是第二次跑到select,就阻塞不返回了)。

后来查出,这是大唐平台特殊之处,select函数会修改参数的timeout的值,每次select被调用返回后,timeout被修改为剩余的时间,所以当timeout被修改为0的时候,select函数就永远阻塞。

因此,需要在while循环里面重新给timeout赋值,才能使得程序正确运行:

    ……

   fd_set readfds;

   struct timeval timeout={1,0}//1秒超时

   ……

while1

{

  FD_ZERO(&readfds);

  FD_SET(sock,&readfds);

timeout={1,0}//需要在这重新赋值,程序才能正确运行

  ret = select(socket+1,&readfds,NULL,NULL,&timeout);

  if(ret>0)

{

    if(FD_ISSET(sock,&readfds))

{

recvfrom(socket,buffer,len,…);

……

}

}

……

}

关于select函数其余参数的修改,可以参考相关的说明文档。需要说明的是,函数对自身参数的修改,是一个不好的设计,增加程序间的耦合,很容易出错。

原创粉丝点击