zoukankan      html  css  js  c++  java
  • select模型的原理、优点、缺点

    关于I/O多路复用:

    I/O多路复用(又被称为“事件驱动”),首先要理解的是,操作系统为你提供了一个功能,当你的某个socket可读或者可写的时候,它可以给你一 个通知。这样当配合非阻塞的socket使用时,只有当系统通知我哪个描述符可读了,我才去执行read操作,可以保证每次read都能读到有效数据而不 做纯返回-1和EAGAIN的无用功。写操作类似。操作系统的这个功能通过select/poll/epoll之类的系统调用来实现,这些函数都可以同时 监视多个描述符的读写就绪状况,这样,**多个描述符的I/O操作都能在一个线程内并发交替地顺序完成,这就叫I/O多路复用,这里的“复用”指的是复用 同一个线程。

    I/O复用之select

    1、介绍:
    select系统调用的目的是:在一段指定时间内,监听用户感兴趣的文件描述符上的可读、可写和异常事件。poll和select应该被归类为这样的系统 调用,它们可以阻塞地同时探测一组支持非阻塞的IO设备,直至某一个设备触发了事件或者超过了指定的等待时间——也就是说它们的职责不是做IO,而是帮助 调用者寻找当前就绪的设备。
    下面是select的原理图:

      

    2 、select系统调用API如下:

    
    
    #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);
    
    

    fd_set结构体是文件描述符集,该结构体实际上是一个整型数组,数组中的每个元素的每一位标记一个文件描述符。fd_set能容纳的文件描述符 数量由FD_SETSIZE指定,一般情况下,FD_SETSIZE等  于1024,这就限制了select能同时处理的文件描述符的总量。

    3、下面介绍一下各个参数的含义:
        1)nfds参数指定被监听的文件描述符的总数。通常被设置为select监听的所有文件描述符中最大值加1;
        2)readfds、writefds、exceptfds分别指向可读、可写和异常等事件对应的文件描述符集合。这三个参数都是传入传出型参数,指的是 在调用select之前,用户把关心的可读、可写、或异常的文件描述   符 通过FD_SET(下面介绍)函数分别添加进readfds、writefds、 exceptfds文件描述符集,select将对这些文件描述符集中的文件描述符进行监听,如果有就绪文件描述符,select会重置readfds、writefds、exceptfds文件描述符集来通知应用程序哪些文件描述符就绪。这个特性将导致select函数返回后,再次调用select之前,必须重置我们关心的文件描述符,也就是三个文件描述符集已经不是我们之前传入 的了。
       3)timeout参数用来指定select函数的超时时间(下面讲select返回值时还会谈及)。

    
    
    struct timeval
    {
        long tv_sec;        //秒数
        long tv_usec;       //微秒数
    };
    
    

    4、下面几个函数(宏实现)用来操纵文件描述符集:

    
    
    void FD_SET(int fd, fd_set *set);   //在set中设置文件描述符fd
    void FD_CLR(int fd, fd_set *set);   //清除set中的fd位
    int  FD_ISSET(int fd, fd_set *set); //判断set中是否设置了文件描述符fd
    void FD_ZERO(fd_set *set);          //清空set中的所有位(在使用文件描述符集前,应该先清空一下)
        //(注意FD_CLR和FD_ZERO的区别,一个是清除某一位,一个是清除所有位)
    
    

    5、select的返回情况:
    1)如果指定timeout为NULL,select会永远等待下去,直到有一个文件描述符就绪,select返回;
    2)如果timeout的指定时间为0,select根本不等待,立即返回;
    3)如果指定一段固定时间,则在这一段时间内,如果有指定的文件描述符就绪,select函数返回,如果超过指定时间,select同样返回。
    4)返回值情况:
    a)超时时间内,如果文件描述符就绪,select返回就绪的文件描述符总数(包括可读、可写和异常),如果没有文件描述符就绪,select返回0;
    b)select调用失败时,返回 -1并设置errno,如果收到信号,select返回 -1并设置errno为EINTR。

    6、文件描述符的就绪条件:
    在网络编程中,
    1)下列情况下socket可读
    a) socket内核接收缓冲区的字节数大于或等于其低水位标记SO_RCVLOWAT;
    b) socket通信的对方关闭连接,此时该socket可读,但是一旦读该socket,会立即返回0(可以用这个方法判断client端是否断开连接);
    c) 监听socket上有新的连接请求;
    d) socket上有未处理的错误。
    2)下列情况下socket可写:
    a) socket内核发送缓冲区的可用字节数大于或等于其低水位标记SO_SNDLOWAT;
    b) socket的读端关闭,此时该socket可写,一旦对该socket进行操作,该进程会收到SIGPIPE信号;
    c) socket使用connect连接成功之后;
    d) socket上有未处理的错误。

    select优点:

       select模型是Windows sockets中最常见的IO模型。它利用select函数实现IO 管理。通过对select函数的调用,应用程序可以判断套接字是否存在数据、能否向该套接字写入据。

        如:在调用recv函数之前,先调用select函数,如果系统没有可读数据那么select函数就会阻塞在这里。当系统存在可读或可写数据时,select函数返回,就可以调用recv函数接   收数据了。

       可以看出使用select模型,需要两次调用函数。第一次调用select函数第二次socket API。使用该模式的好处是:可以等待多个套接字。

    select缺点:
    (1)每次调⽤用select,都需要把fd集合从⽤用户态拷贝到内核态,这个开销在fd很多时会很⼤大
    (2)同时每次调⽤用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很⼤大
    (3)select⽀支持的⽂文件描述符数量太⼩小了,默认是1024

  • 相关阅读:
    LR的九种参数取值方法
    性能测试过程总结
    LR 中webservice三种使用方法
    LR解决保存后后台为乱码问题
    LoadRunner 实现监控Tomcat
    LR12 WebTour注册
    LoadRunner12安装说明以及问题解决
    使用Python访问网络数据 python network-data 第六章
    使用Python访问网络数据 python network-data 第五章
    反射调用私有方法
  • 原文地址:https://www.cnblogs.com/-zyj/p/5719923.html
Copyright © 2011-2022 走看看