linux中 select() 函数的第一个参数为什么是监听的最大描述符加1呢

select() 函数原型:

      /* According to POSIX.1-2001 */
       #include <sys/select.h>

       /* According to earlier standards */
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

nfds:表示需要监听的文件描述符的最大值 + 1;(即待测试的描述集的总个数)

那为什么需要 + 1呢?

因为待测试的描述集总是从0, 1, 2, ...开始的;所以,如果要检测的描述符为9, 10, 那么系统实际也要监测0, 1, 2, 3, 4, 5, 6,  7,8;  此时真正待测试的描述符的个数为11个, 也就是 MAX(9, 10) + 1;

有两点要注意:

       1.  如果你要检测的文件描述符是9,10,但是你把select的第一个参数定为9, 实际上只检测0到8, 所以select不会感知到 9,10文件描述符的变化。

       2.  如果你要检测的文件描述符是9,10,且你把select的第一个参数定为11, 实际上会检测0-10, 但是如果你不把描述如0 set到描述符中, 那么select也不会感知到0描述符的变化。

        所以, select感知到描述符变化的必要条件是, 第一个参数要合理, 比如定义为fdMax+1,  且把需要检测的文件描述符set到描述集中。

可使用以下代码来测试下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/time.h>
#include<sys/types.h>
 
int main(void)
{
    struct timeval tv; 
    tv.tv_sec = 10;
    tv.tv_usec = 500; // us
 
    fd_set rdfds;
    FD_ZERO(&rdfds); 
    FD_SET(STDIN_FILENO, &rdfds); // STDIN_FILENO是标准输入, 加入描述集
    
    int ret= select(STDIN_FILENO + 1, &rdfds, NULL, NULL, &tv);
    if (ret < 0) {
        printf("selcet error, ret = %d\n", ret);
        return -1;
    } else if (ret == 0) {
        printf("timeout \n");
    }
    printf("ret = %d \n", ret); 
    return 0;
}

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值