select函数有时会改变第二个参数readfds的值

时间:2015-10-16 09:15:11

标签: linux sockets select sleep

这是代码:

FD_ZERO(&t_set);
num = 0;
maxfd = 0;

while (num < MAX)
{
    if ((sockfd = connectSocket(ptr)))
        ;
    //printf("connect to server succeed!\n%d\n", fd);
    else
    {
        fprintf(stderr, "connect error\n");
        exit(1);
    }

    if (!writeSocket(sockfd, ptr))
        ;
        //printf("write to server succeed!\n");
    else
    {
        fprintf(stderr, "write error\n");
        exit(1);
    }
    if (maxfd < sockfd)
        maxfd = sockfd;
    FD_SET(sockfd, &t_set);
    printf("%d\n", t_set);
    memset(fileName, 0, BUFSIZE);
    sprintf(fileName,"%d.html", sockfd);
    if ((filefd = open(fileName, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) == -1)
    {
        printf("create file failed!\n");
        return -1;
    }
    ff[num].sockfd = sockfd;
    ff[num].filefd = filefd;
    ++num;
}
printf(">------------------->\n");  
while (1) 
{
    //sleep(1);
    tv.tv_sec = 1;
    tv.tv_usec = 0;
    h = 0;
    printf("%d\n", t_set);           //print the t_set before select
    h = select(maxfd + 1, &t_set, NULL, NULL, &tv);
    printf("%d\n", t_set);           //print the t_set after select
    printf(">------------------->\n");  
    //fd_set is an array of long;
    //if use printf("%d %d", t_set, h); secondly may print the second value of t_set , not h;
    if (h < 0)
    {
        fprintf(stderr, "select error");
        return -1;
    }
    if (h == 0)
    {
        fprintf(stderr, "select return 0\n");
        break;
    }
    else
    {
        int n = 0;
        while (!FD_ISSET(ff[n].sockfd, &t_set))
            ++n;
        if (readSocket(ff[n].sockfd, ff[n].filefd))
        {
            FD_CLR(ff[n].sockfd, &t_set);
            printf("===================== %d\n", n);
        }
    }

}

num = 0;
while (num++ < MAX)
    close(ff[num].filefd);

输出:

8           // initial of t_set
40
168
680
2728
>------------------->
2728       // the two value were print before and after the select;
680
>------------------->
680
680
>------------------->
680
680
>------------------->
680
680

打印t_set的值,我发现在第一个和最后一个循环调用select后,t_set的值发生了变化。 如果在select之前添加sleep(1)并设置tv_set.sec = 0,tv_usec = 0,则使用sleep timeout替换select timeout,t_set执行正常。 还有另一个问题,上面的例子不能监视最后一个套接字,使用睡眠改变也可以修复问题;

感谢任何建议!

1 个答案:

答案 0 :(得分:0)

从select(2)手册页:

&#34;退出时,系统[即readfswritefdsexceptfds]会在适当位置进行修改,以指示哪些文件描述符实际更改了状态。&# 34;

您只使用readfs,但假设select系统调用修改。