源地址:http://my.oschina.net/pathenon/blog/64090

select的功能可以用一句话来描述: 实现基于I/O多路复用的异步并发编程。 在具体讲解select之前我们先看看常规的阻塞socket编程方式,以服务端为例:

     
    对于这种方式,最大的问题在哪里呢?accept和recev的阻塞调用!下面以两种场景为例,来说明相比这种情况,select是如何做到异步I/O多路复用的高效性。
 
     第一种场景: server除了要对外响应client的服务外,还要能够接受标准输入的命令来进行管理。
    
        假如使用上述阻塞方式,在单线程中,accept调用和read调用必定有先后顺序,而它们都是阻塞的。比如先调用accept,后调用    read,那么如果没有客户请求时,服务器会一直阻塞在accept,没有机会调用read,也就不能响应标准输入的命令。    
1 int fd_stdin = open(...);
2 int fd_socket = socket(...);
3 bind(...);
4 listen(...);
5 while(1){
6   accept(...);
7   read(...);
8 }
        而如果使用select,先注册分别由socket和open创建的文件描述符,然后进入select调用。当其中任何一个文件描述符的状态发生改变时,就可以进行相应的处理。
01 int fd_stdin = open(...);
02 int fd_socket = socket(...);
03 bind(...);
04 listen(...);
05 fd_set fs;
06 while(1){
07   FD_ZERO(fs...);
08   FD_SET(fd_stdin, fs);
09   FD_SET(fd_socket, fs);
10   select();
11   if(FD_ISSET(fd_socket...))
12         accept(...);
13   if(FD_ISSET(fd_stdin...))
14         read(...);
15 }
         
     第二种场景: server要对外提供大量的client请求服务。
 
        假如使用阻塞方式,在单线程中,由于accept和recev都是阻塞式的,那么当一个client被服务器accept后,它可能在send发送消息时阻塞,因此服务器就会阻塞在recev调用。即时此时有其他的client进行connect,也无法进行响应。
1 int fd_socket = socket(...);
2 bind(...);
3 listen(...);
4 while(1){
5     accept(...);
6     revev(...);
7 }
        而如果使用select,在服务器端先注册由socket创建的文件描述符,然后进入select调用。只有当由socket创建的文件描述符的状态发生改变时,才执行accept操作,并把得到的client的文件描述符进行注册,再次进入select调用。当select检查到有文件描述符的状态改变时,如果是server的socket创建的文件描述符,则执行accept操作,否则执行recev操作。当请求的client数目比较多时, select明显能够提高并发性。
01 int fd_socket = socket(...);
02 bind(...);
03 listen(...);
04 fd_set fs;
05 while(1){
06     FD_ZERO(fs...);
07     FD_SET(fd_socket, fs);
08     set fs with the file descriptor fd_accept got from accept;
09     select();
10     if(FD_ISSET(fd_socket...)){
11         accept(...);
12         record the file descriptor;
13     }
14               
15     if(FD_ISSET(fd_accept...))
16         recv(...);
17 }
    
    说完了select相比阻塞调用的好处,我们也简单说说它的 限制和不足
    (1)select在查找状态改变的文件描述符时,是对描述符链表进行遍历操作,因此对效率有较大影响。
    (2)select在默认情况下,支持的最大文件描述符个数为1024。当然,可以通过修改linux的socket内核进行修改。
 
    PS:本博客的主要用途是记录在准备找工作过程中对以前所学知识的复习笔记。由于时间关系,大部分文章都没有进入深入的细节讲解。忘海涵!

转I/O多路复用之select的更多相关文章

  1. IO多路复用之select

    IO多路复用之select总结   1.基本概念 IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程.IO多路复用适用如下场合: (1)当客户处理多个描述字时(一般是交 ...

  2. 网络通信 --> IO多路复用之select、poll、epoll详解

    IO多路复用之select.poll.epoll详解      目前支持I/O多路复用的系统调用有 select,pselect,poll,epoll,I/O多路复用就是通过一种机制,一个进程可以监视 ...

  3. python网络编程——IO多路复用之select

    1 IO多路复用的概念 原生socket客户端在与服务端建立连接时,即服务端调用accept方法时是阻塞的,同时服务端和客户端在收发数据(调用recv.send.sendall)时也是阻塞的.原生so ...

  4. 【python】-- IO多路复用(select、poll、epoll)介绍及实现

    IO多路复用(select.poll.epoll)介绍及select.epoll的实现 IO多路复用中包括 select.pool.epoll,这些都属于同步,还不属于异步 一.IO多路复用介绍 1. ...

  5. Python——IO多路复用之select模块epoll方法

    Python——IO多路复用之select模块epoll方法 使用epoll方法实现IO多路复用,使用方法基本与poll方法一致,epoll效率要高于select和poll. .├── epoll_c ...

  6. Python——IO多路复用之select模块poll方法

    Python——IO多路复用之select模块poll方法 使用poll方法实现IO多路复用 .├── poll_client.py├── poll_server.py└── settings.py ...

  7. Python——IO多路复用之select模块select方法

    Python——IO多路复用之select模块select方法 使用select模块的select方法实现Python——IO多路复用 实现同时将终端输入的文本以及客户端传输的文本写入文本文件中: w ...

  8. IO多路复用(select、poll、epoll)介绍及select、epoll的实现

    IO多路复用(select.poll.epoll)介绍及select.epoll的实现 IO多路复用中包括 select.pool.epoll,这些都属于同步,还不属于异步 一.IO多路复用介绍 1. ...

  9. IO多路复用之select、poll、epoll

    本文转载自IO多路复用之select.poll.epoll 导语 IO多路复用:通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. ...

  10. IO多路复用之select总结

    1.基本概念 IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程.IO多路复用适用如下场合: (1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/ ...

随机推荐

  1. HTML5能取代Android和iOS应用程序吗?

    大量新生移动设备的兴起,改变了互联网的未来.在技术的发展上,HTML5会取代App应用吗?或者说能够在多大程度上取代呢?在HTML5规范中,已经加入了相机.磁力罗盘.GPS信息的支持.很多新兴浏览器也 ...

  2. 论文阅读-(ECCV 2018) Second-order Democratic Aggregation

    本文是Tsung-Yu Lin大神所作(B-CNN一作),主要是探究了一种无序的池化方法\(\gamma\) -democratic aggregators,可以最小化干扰信息或者对二阶特征的内容均等 ...

  3. 数组,List,Set相互转化

    1.数组转化为List: String[] strArray= new String[]{"Tom", "Bob", "Jane"}; Li ...

  4. pom.xml文件配置maven仓库地址

    中央仓库就是Maven的一个默认的远程仓库,Maven的安装文件中自带了中央仓库的配置($M2_HOME/lib/maven-model-builder.jar) 在很多情况下,默认的中央仓库无法满足 ...

  5. Linux用户管理 (3)

    用户管理 1 用户添加 基本语法 useradd [选项] 用户名 添加一个用户: 注意事项 1)当用户创建成功后,会自动的创建和用户同名的家目录 2)也可以通过 useradd -d 指定目录 新的 ...

  6. 查看linux的shhd端口号 netstat | grep sshd

    [root@iZ2zef51hufoaycipfxek8Z ~]# [root@iZ2zef51hufoaycipfxek8Z ~]# netstat | grep sshd [root@iZ2zef ...

  7. JS规则 编程练习 考考大家的数学,计算以下计算公式的结果。然后在浏览器中运行一下,看看结果是否跟你的结果一致。

    编程练习 考考大家的数学,计算以下计算公式的结果.然后在浏览器中运行一下,看看结果是否跟你的结果一致. 任务 第一步: 在  ? 处填写你的答案. 第二步: 填写完成后,运行一下,看看是不是跟你填写的 ...

  8. ie中onclick问题

    代码:<button > <span onclick="xxx();">确定</span></button> 在chrome和fir ...

  9. python类的静态方法和类方法区别

    先看语法,python 类语法中有三种方法,实例方法,静态方法,类方法. # coding:utf-8 class Foo(object): """类三种方法语法形式&q ...

  10. BZOJ 1579 [Usaco2009 Feb]Revamping Trails 道路升级

    堆优化的dijkstra. 把一个点拆成k个. 日常空间要开炸一次.. //Twenty #include<cstdio> #include<cstring> #include ...