2018-07-31 (星期二)
I/O复用:
    一个应用程序通常需要服务一个以上的文件描述符.
    例如stdin,stdout,进程间通信以及若干文件进行I/O,如果不借助线程的话,(线程通常在同一时间无法服务一个以上文件描述符),就是分开每个所要服务的文件描述符,这样做有个问题,就是一旦遇到一个没有准备好的文件描述符,进程就会受阻,可能只受阻几秒,但是用户体验就会大大下降.借助线程,那么进程要维护额外的线程,线程的创建,销毁会增加很多资源.
    因此就出现了I/O复用这个问题.
运作方式:
    1.I/O复用:当这些文件描述符中有任何一个就绪可进行I/O,请通知我.
    2.休眠:直到有一个或多个文件描述符准备妥当.
    3.唤醒:什么准备就绪了?
    4.处理所有就绪可进行I/O的文件描述符而不收到阻挡.
    5.回到步骤1,从头开始.
linux提供了三种方案:select,poll,epoll(高级)
select模型:

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h> int select (int n,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout); FD_CLR(int fd, fd_set *set); 将某个文件描述符移除 FD_ISSET(int fd, fd_set *set); 判断fd是否属于分组(可在调用后判断某个文件描述符是否就绪:
if (FD_ISSET(fd, &readfds))
/* fd 可供读取不会受到阻挡 */ FD_SET(int fd, fd_set *set); 将fd加入分组中 FD_ZERO(fd_set *set); 讲分组中所有文件描述符移除

select()系统调用监视的文件描述符分成三个部分,每个部分等待不同的事件:
    readfds分组中的文件描述符用于查看是否读取受阻.
    writefds分组中的文件描述符用于查看是否写入受阻.
    exceptfds分组中的文件描述符用于查看是否有异常或者是否有紧急数据.

调用返回所有可用文件描述符.
参数n等于任何分组中最高编号的文件描述符值+1.
timeout参数是一个指向timeval结构的指针,该结构的定义如下:

#include <sys/time.h>

strcut timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};

如果此参数不是NULL,那么select() 调用将在tv_sec秒和tv_usec微秒之后返回.(有点强制的意思,就算没有就绪的,也得返回)

select 当返回为正数时,表示已经准备好的描述符数。返回0时表示超时。发生错误返回-1,并且将errno指定为下面的其中一个值:
    EBADF    分组中提供了一个无效的文件描述符.
    EINTR    等待时捕捉到一个信号,你可以再次调用select().
    EINVAL    参数n是负值或者给定timeout是无效值.
    ENOMEM    内存不足以完成这项要求.

使用select()去油可以执行的休眠机制
需要可移植性的休眠机制时,往往采用select(), 方法是提供非NULL值的timeout参数,但是三个分组参数全部为NULL:

struct timeval tv;
tv.tv_sec = ;
tv.tv_usec = ;
/* 休眠500毫秒 */
select (, NULL, NULL, NULL, &tv);

当然,Linux也会为高分辨率休眠机制提供接口.

小例子:

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h> #define TIMEOUT 5 /*select的等待时间,以秒为单位 */
#define BUF_LEN 1024 /* 读取缓冲区,以字节为单位 */ int main(void) {
struct timeval tv;
fd_set readfds;
int ret; /* 等候stdin的输入数据 */
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds); /* 等候5秒的时间 */
tv.tv_sec = TIMEOUT;
tv.tv_usec = ; /* 好了,开始提供服务! */
ret = select (STDIN_FILENO + ,
&readfds,
NULL,
NULL,
&tv);
if (ret == -) {
perror ("select");
return ;
} else if (!ret) {
printf("%d seconds elapsed.\n", TIMEOUT);
return ;
} /*
* 我们的文件描述符可供读取了吗?
* (肯定可以,因此他是我们所提供的唯一fd,
* 而且次调用会返回非零值,但是我们还想有自己一默)
*/
if (FD_ISSET(STDIN_FILENO, &readfds)) {
char buf[BUF_LEN+];
int len;
/* 保证不会遭到阻挡 */
len = read (STDIN_FILENO, buf, BUF_LEN);
if (len == -) {
perror ("read");
return -;
}
if (len) {
buf[len] = '\0';
printf ("read: %s\n", buf);
return ;
}
}
fprintf (stderr, "This should not happen!\n");
return ;
}

I/O复用----select的更多相关文章

  1. I/O复用-select模型

    IO复用: I/O复用使得程序可以同时监听多个文件描述符,这对提高程序的性能至关重要.例如TCP服务器要同时处理监听socket和连接socket,客户端要同时处理用户输入和网络连接. Linux下实 ...

  2. I/O复用——select和poll

    概述 I/O多路复用(multiplexing)的本质是通过一种机制(系统内核缓冲I/O数据),让单个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是读就绪或写就绪),能够通知程序进行相应的读写 ...

  3. I/O复用select 使用简介

    一:五种I/O模型区分: 1.阻塞I/O模型      最流行的I/O模型是阻塞I/O模型,缺省情形下,所有套接口都是阻塞的.我们以数据报套接口为例来讲解此模型(我们使用UDP而不是TCP作为例子的原 ...

  4. io复用select方法编写的服务器

    摘要:io多路复用是通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般都是读就绪或者写就绪),就能通知应用程序进行相应的读写操作.select函数作为io多路复用的机制,第一个参数nfds是f ...

  5. I/O复用(select)——回声服务器端/客户端

    一.select 使用select函数可以将多个文件描述符集中到一起统一监视,监视事件如下: 是否存在待读取数据. 是否可传输无阻塞传输数据. 是否发生异常. 将关心上述3种事件的文件描述发分别注册到 ...

  6. 多线程 or I/O复用select/epoll

    1:多线程模型适用于处理短连接,且连接的打开关闭非常频繁的情形,但不适合处理长连接.线程模型默认情况下,在Linux下每个线程会开8M的栈空间,在TCP长连接的情况下,以2000/分钟的请求为例,几乎 ...

  7. 高性能网络服务器--I/O复用 select poll epoll_wait之间的区别

    一.select select采用的是集合的方式,最多只能访问1024个套接字.可读,可写,异常,三种访问,并且采用的是轮训的方式进行每次访问都需要从内核向用户空间拷贝 二.poll poll采用的是 ...

  8. IO复用——select系统调用

    1.select函数 此函数用于在一段时间内,监听用户感兴趣的文件描述符上的可读.可写和异常等事件. #include<sys/select.h> int select(int nfds, ...

  9. Linux下I/O复用 Select与Poll

    Select #include <sys/time.h>#include <sys/types.h>#include <sys/unistd.h> int sele ...

随机推荐

  1. PyYAML学习第一篇

    1. YAML是一种交互式和可读性强的脚本语言.脚本语言都是解释性语言. PyYAML是YAML语言的编辑器和解释器.在python语言里面有PyYAML的安装包. 相关学习文档:http://pyy ...

  2. 从零学习安全测试,从XSS漏洞攻击和防御开始

    WeTest 导读 本篇包含了XSS漏洞攻击及防御详细介绍,包括漏洞基础.XSS基础.编码基础.XSS Payload.XSS攻击防御. 第一部分:漏洞攻防基础知识   XSS属于漏洞攻防,我们要研究 ...

  3. C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 – 员工离职管理

    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 – 员工离职管理 当公司有几万人,上千家加盟网点,几个庞大的直属分公司后,系统账户的有效管理也是一个头疼的问题,把所有的帐户及时进行科学 ...

  4. spring + mybatis 注解 @Transactional失效

    1.问题 在使用@Transactional注解管理事务的时候会出现很多错误,比如: *** was not registered for synchronization because synchr ...

  5. [HNOI2017]大佬

    参考题解 \(\text{Solution}\) 我们发现5个行为中2操作与其它操作无关,所以我们采用贪心,尽量让多的时间去攻击大佬. 设 \(f[i][j]\) 表示前 \(i\) 天剩 \(j\) ...

  6. Turtlebot

    Turtlebot2 数据分析: imu信息:只有z轴的旋转yaw,没有xy的角速度. odom:利用轮速计,提供平移变换,没有z方向的平移. 好的网站,详细介绍了turtlebot的使用:https ...

  7. Thunder团队第三周 - Scrum会议3

    Scrum会议3 小组名称:Thunder 项目名称:i阅app Scrum Master:代秋彤 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传 ...

  8. Java常用类之File类

    File 类: 1. java.io.File 类代表系统文件名(路径名.文件名); 2. File 类常见的构造方法: 2.1. File(String pathname):通过将给定路径名字符串转 ...

  9. Swift-map()跟flatMap()区别

    map()方法介绍 map() 是  Array 提供的方法,通过接收一个函数作为传入参数,对数组中每个元素进行函数变换得到新的结果值.这样只需要提供  X->Y 的映射关系,就能将数组  [X ...

  10. HDU 2133 What day is it

    http://acm.hdu.edu.cn/showproblem.php?pid=2133 Problem Description Today is Saturday, 17th Nov,2007. ...