zoukankan      html  css  js  c++  java
  • select函数

    axel中的axel_do函数中使用了select()函数,碰巧我正在看UNP的第六章讲的也是select函数,所以简单总结一下。

    这里先列出axel_do函数中使用的select。

        FD_ZERO( fds );
        hifd = 0;
        for( i = 0; i < axel->conf->num_connections; i ++ )
        {
            if( axel->conn[i].enabled )
                FD_SET( axel->conn[i].fd, fds );
            hifd = max( hifd, axel->conn[i].fd );
        }
        if( hifd == 0 )
        {
            /* No connections yet. Wait...                */
            usleep( 100000 );
            goto conn_check;
        }
        else
        {
            timeval->tv_sec = 0;
            timeval->tv_usec = 100000;
            /* A select() error probably means it was interrupted
               by a signal, or that something else's very wrong...    */
            if( select( hifd + 1, fds, NULL, NULL, timeval ) == -1 )
            {
                axel->ready = -1;
                return;
            }
        }
        
        /* Handle connections which need attention            */
        for( i = 0; i < axel->conf->num_connections; i ++ )
        if( axel->conn[i].enabled ) {
        if( FD_ISSET( axel->conn[i].fd, fds ) )
        {
            axel->conn[i].last_transfer = gettime();
            size = read( axel->conn[i].fd, buffer, axel->conf->buffer_size );
            if( size == -1 )
            {
                if( axel->conf->verbose )
                {
                    axel_message( axel, _("Error on connection %i! "
                        "Connection closed"), i );
                }
                axel->conn[i].enabled = 0;
                conn_disconnect( &axel->conn[i] );
                continue;
            }

    为啥要使用select()

    那么为啥需要使用select()函数呢?换句话说select函数的作用是啥?引用一句UNP上的话:

    “select函数允许进程指示内核等待多个事件中的任何一个发生,并仅在有一个或多个事件发生或者经历一段指定的事件后才唤醒它。”

    换句话说,有一个容器里面装了若干个事件,这些事件发生的顺序不清楚,但是发生之后要进行相应的处理。select函数的作用就是保持阻塞直到这些事件中的某一个发生,或者没事件发生的但过了一段指定的时间(超时时间)。

    那么axel_do函数中使用的select的用意是啥呢?

    其实从上面的代码中很容易看出来,这段代码的作用是要读有数据过来的socket。而axel在下载的时候是多连接的,我们不知道什么时候哪一个socket准备好了,于是不可能阻塞在一个socket上,取而代之的是阻塞在select函数上,直到有socket准备好,这样显然增加了效率。

    先给出select()的原型:

    int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);

    ·fd_set实际上是一个long的数组,fd_set数组中每一位对应一个描述符,就像是位(bit)一样,当某一位被置位,说明这一位对应的描述符在当前的描述符集合里。

    timeout就是超时时间。

    readfds,writefds,errorfds分别代表的是测试可读、可写、异常的描述符集合。

    和select函数相关的四个宏:

    FD_ZERO(fd_set *fdset)
    FD_SET(int fd, fd_set *fdset)

    FD_CLR(int fd, fd_set *fdset)
    FD_ISSET(int fd, fdset *fdset)

    清除fdset集合
    将fd在fdset集合中置位,也就是将fd加入fdset
    在fdset集合中清楚fd
    测试fd是否在fdset中置位
  • 相关阅读:
    wxpython 浏览器框架
    wxpython 开发播放器
    Docker学习(三)——Docker镜像使用
    Docker学习(二)——Docker容器使用
    SSL/TLS协议
    Https原理及证书管理
    证书及证书管理
    Docker学习(一)——安装docker
    Linux系统中安装软件方法总结
    Linux下删除的文件如何恢复
  • 原文地址:https://www.cnblogs.com/jaletech/p/3393336.html
Copyright © 2011-2022 走看看