源地址: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. <Python基础>装饰器的基本原理

    1.装饰器 所谓装饰器一般是对已经使用(上线)的函数增加功能. 但是因为一般的大公司的严格按照开放封闭原则(对扩展是开放的,对修改是封闭的),不会让你修改原本的函数. 装饰器就是在不改变原本的函数且不 ...

  2. 矩阵连乘 /// 区间DP oj1900

    题目大意: 输入t :t为测试用例个数 接下来t个测试 每个测试用例 第一行输入n: n为矩阵个数 保证n个矩阵依序是可乘的 接下来n行 每行输入p,q:p为长度q为宽度 对给定的n个矩阵确定一个计算 ...

  3. easyui treegrid的使用示例

    一.前端: <div id="tbList" fit="true"></div> $(function () { $("#tb ...

  4. JS流程控制语句 做判断(if语句)if语句是基于条件成立才执行相应代码时使用的语句。语法:if(条件) { 条件成立时执行代码}

    做判断(if语句) if语句是基于条件成立才执行相应代码时使用的语句. 语法: if(条件) { 条件成立时执行代码} 注意:if小写,大写字母(IF)会出错! 假设你应聘web前端技术开发岗位,如果 ...

  5. Linux安装Java与Eclipse

    Linux安装Java和Eclipse 一.准备工作 1.下载jdk  https://www.oracle.com/technetwork/java/javase/downloads/jdk8-do ...

  6. UNIX环境高级编程------apue.h找不到

    运行1-3代码时,出现问题:apue.h 没有找到问题 1.去此网址下载源码: http://www.apuebook.com/code3e.html 压缩包名为:src.3e.tar.gz 2.解压 ...

  7. 健壮的 Java 基准测试

    健壮的 Java 基准测试 健壮的 Java 基准测试,第 1 部分: 问题 了解 Java 代码基准测试的问题 Brent Boyer, 程序员, Elliptic Group, Inc. 简介:程 ...

  8. Django之深入了解视图层

    目录 视图层三板斧 HttpResponse render redirect JsonResponse FBV CBV CBV源码 如何给FBV和CBV加装饰器 视图层三板斧 规定视图函数必须有一个返 ...

  9. CF148D Bag of mice (期望dp)

    传送门 # 解题思路 ​    ~~这怕是本蒟蒻第一个独立做出来的期望$dp$的题,发篇题解庆祝一下~~.首先,应该是能比较自然的想出状态设计$f[i][j][0/1]$ 表示当前还剩 $i$个白老鼠 ...

  10. dijkstra (模板)

    突然意识到以前写的都是假的dij,感谢GhostCai神犇. #include<iostream> #include<cstdio> #include<cstring&g ...