如何在C中超时后调用select?

时间:2016-04-22 06:27:15

标签: c

我使用选择进行同步I / O多路复用。它将检查任何数据1秒。如果没有数据,1秒后它将显示输出(puts("Waited for 1 sec no data");)然后它将再次检查数据。但这只是在第一次工作然后它进入无限循环。 有没有替代解决方案。

//..............................
//.............................
//Creating listener socket and other sort of things
struct timeval tv;
        tv.tv_sec=1;
        tv.tv_usec=0;

    while(1)
    {
    FD_ZERO(master);


    FD_SET(listener,master);
    fdmax = listener;
    int retval=select(fdmax+1,master, NULL, NULL,&tv);
    printf("retval is %d\n",retval);

            if(retval == -1)
            {
                    perror("Server-select() error");
            }else if(retval)
            {
                    puts("Data available");
                    //If there is no data do some work and checkagain.

            }else
            {
                    puts("Waited for 1 sec no data"); 
                    //If there is no data do some work and checkagain.

            }
      }

2 个答案:

答案 0 :(得分:2)

来自man select

  

在Linux上,select()修改超时以反映未睡眠的时间;大多数其他实现不会这样做。 (POSIX.1-2001允许任何一种行为。)当读取超时的Linux代码移植到其他操作系统时,以及当代码移植到Linux时,在循环中为多个select()s重用struct timeval时,这会导致问题重新初始化它。在select()返回后,请考虑超时未定义。

master一样,您必须在每次tv来电之前设置select

在我的代码中,我经常有类似的东西:

FD_ZERO(master);
FD_SET(listener,master);
fdmax = listener;

while (1)
{
    struct timeval tv = {1, 0};

    int retval=select(fdmax+1,master, NULL, NULL,&tv);
    printf("retval is %d\n",retval);

    if(retval == -1) {
        perror("Server-select() error");
        break; //  <-- notice the break here
    } else if(retval) {
        puts("Data available");
    } else {
        puts("Waited for 1 sec no data"); 
    }
}

答案 1 :(得分:0)

除了Mathieu答案外,似乎在每次调用FD_ZERO之前都必须先将其调用为空的可读文件句柄集,然后再调用FD_SET。

我一直在努力选择()在到达超时后始终返回0的事实,无论是否有要读取的数据(我从键盘上读取输入,我用'cat'命令检查了每次按键时都发送数据)

代码应为(记入先前答案):

while (1)
{

    struct timeval tv = {1, 0};
    FD_ZERO(master);
    FD_SET(listener,master);
    fdmax = listener;

    int retval=select(fdmax+1,master, NULL, NULL,&tv);
    printf("retval is %d\n",retval);

    if(retval == -1) {
        perror("Server-select() error");
        break; //  <-- notice the break here
    } else if(retval) {
        puts("Data available");
    } else {
        puts("Waited for 1 sec no data"); 
    }
}