• select机制


    select机制

    函数作用:

    在一段时间指定的时间内,监听用户感兴趣的文件描述符上可读、可写和异常事件。

    函数原型:
    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>
    int select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
    
    参数说明:

    maxfds:

    maxfds:是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错。
    在linux系统中,select的默认最大值为1024。
    设置这个值的目的是为了不用每次都去轮询这1024个fd,假设我们只需要几个套接字,我们就可以用最大的那个套接字的值加上1作为这个参数的值,当我们在等待是否有套接字准备就绪时,只需要监测maxfd+1个套接字就可以了,这样可以减少轮询时间以及系统的开销。
    

    readfds:

    readfds:首先需要明白,fd_set是什么数据类型,有一点像int,又有点像struct,其实,fd_set声明的是一个集合,也就是说,readfs是一个容器,里面可以容纳多个文件描述符,把需要监视的描述符放入这个集合中,当有文件描述符可读时,select就会返回一个大于0的值,表示有文件可读;
    

    writefds:

    和readfs类似,表示有一个可写的文件描述符集合,当有文件可写时,select就会返回一个大于0的值,表示有文件可写;
    

    errorfds

    同上面两个参数的意图,用来监视文件错误异常文件。
    

    timeout:

    这个参数一出来就可以知道,可以选择阻塞,可以选择非阻塞,还可以选择定时返回。
    当将timeout置为NULL时,表明此时select是阻塞的;
    当将tineout设置为timeout->tv_sec = 0,timeout->tv_usec = 0时,表明这个函数为非阻塞;
    当将timeout设置为非0的时间,表明select有超时时间,当这个时间走完,select函数就会返回。
    从这个角度看,个人觉得可以用select来做超时处理,因为你如果使用recv函数的话,你还需要去设置recv的模式,麻烦的很。
    

    返回值

    = 0 表示超时
    < 0 select失败
    > 0 成功,表示就绪的描述符的个数
    

    举例1:创建一个线程,每100ms轮训一次,使用select设置timeout时间。

    struct timeval
    {      
        long tv_sec;   /*秒 */
        long tv_usec;  /*微秒 */   
    };
    
    int func1()
    {
        struct timeval time;
        time->tv_sec = 0;
        time->tv_usec = 100000;
        int32_t ret = select(0, nullptr, nullptr, nullptr, time);
        if (ret == 0) {
            // 100ms超时时间到,可以处理相应的task等
        } else if (ret < 0) {
            // 函数select出错
        } else {
            // 不会出现这种情况,因为我们没有监听任何描述符
        }
        return 1;
    }
    int main()
    {
        while(func1() == 1){}; // 一直循环处理,每100ms处理一次task
    }
    ####select总结:
    1、使用select监听socket时是线性扫描的方式,即采用轮询的方式,当套接字比较多的时候,每次select都要遍历每个socket来完成调度,不管哪个socket是活跃的,都会遍历一遍,这很浪费CPU的时间,如果每个套接字都能注册一个回调函数,当套接字活跃时直接调用回调也是很方便的,这样就避免了轮训,这正是epoll和equeue做的事情。
    
    2、
    
    
  • 相关阅读:
    接口测试的一个正常取值的实例
    接口测试的常见问题
    多接口(增删改查接口)的组合测试流程
    深入理解Java面向对象三大特性 封装 继承 多态
    vue.js入门
    Java,vue.js,jsp for循环的写法
    js的重载
    js的函数作用域
    闭包是什么以及封闭包怎么产生的?
    Leetcode 234. Palindrome Linked List
  • 原文地址:https://www.cnblogs.com/wangdongfang/p/13849932.html
Copyright © 2020-2023  润新知