一、I/O复用典型的网络应用场合

  • 当客户处理多个描述字时,必须使用I/O复用,这在前一段中已做了描述。
  • 一个客户同时处理多个套接口时可能的,但很少出现。
  • 如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用。
  • 如果一个服务器即要处理TCP,又要处理UDP。
  • 如果一个服务器要处理多个服务或者多个协议。

二、I/O模型

一个输入操作一般有两个不同的阶段:

1.等待数据准备好

2.从内核到进程拷贝数据

五个I/O模型基本区别:

  • 阻塞I/O

此系统调用直到数据报到达切拷贝到应用缓冲区或是出错才返回。

  • 非阻塞I/O模型

前三次调用recvfrom任无数据返回,因此内核立即返回一个EWOULDBLOCK错误。

第四次调用recvfrom时,数据已准备好,被拷贝到应用缓冲区,recvfrom返回成功指示。

一直调用recvfrom称之为轮询,这会对CPU时间极大浪费。

  • I/O复用模型

调用select或poll,在这两个系统调用中的某一个上阻塞,而不是阻塞于真正的I/O系统调用。

我们阻塞select调用,等待数据报套接口可读。当select返回套接口可读条件时,我们调用recvfrom将数据报拷贝到应用缓冲区中。

这一种和第一种比较没有什么优越性,而且调用了两次系统调用。但是select可以等待多个描述字。

  • 信号驱动I/O模型

我们也可以用信号,让内核描述字准备好时用信号SIGIO通知我们。

先要允许套接口进行信号驱动I/O,并通过系统调用sigaction安装一个信号处理程序。

此系统调用立即返回,进程继续工作,它是非阻塞的。数据准备好被读时,就为该进程生成一个SIGIO信号。

我们可以在信号处理程序中调用recvfrom来读取数据报,并通知主循环来处理。(也可以通知主循环读取)

信号的好处是,不阻塞,主循环可以继续执行。

  • 异步I/O模型

和上一个信号驱动I/O由内核通知我们何时可以启动一个I/O操作,异步I/O是由内核通知我们I/O操作何时完成。

三、select函数

#include <sys/select.h>
#include <sys/time.h> int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset
const struct timeval *timeout);
返回:准备好描述字的正数目0超时,-1出错
maxfdp1:整数值,集合中所有文件描述符范围,所有文件描述符中的最大值+1
readset:指向一组等待可读性检查的套接口
writeset:指向一组等待可写性检查的套接口
exceptset:指向一组等待错误检查的套接口
timeout:select()最多等待时间,对阻塞操作则为NULL

timeout有三种可能:

1.永远等待下去:仅在有一个描述字准备好I/O时才返回,为此,我们将参数timeout设置为空指针

2.等待固定时间:再有一个描述字准备好I/O后返回,但不超过timeout

3.根本不等待:检查描述字后立即返回,这称为轮询。timeout指向0

对于上面的fd_set数据类型,唯一可以进行处理的是:分配一个这种类型的变量,将这种类型的一个变量赋值给同类的另一个变量,或使用下面函数。

#include <sys/select.h>

int FD_ISSET(int fd, fd_set *fdset);  /*在调用select()函数后,用FD_ISSET来检测fd是否在set集合中,当检测到fd在set中则返回真,否则,返回假(0)*/
返回:若fd在描述符集中,返回非0值,否则返回0
void FD_CLR(int fd, fd_set *fdset);  /*将fd从set集合中清除*/
void FD_SET(int fd, fd_set *fdset);  /*将fd加入set集合*/
void FD_ZERO(fd_set *fdset);  /*将set清零使集合中不含任何fd*/

相关的还有fd_set

typedef struct
{
/*XPG4.2requires this member name.Otherwise avoid the name
from the global name space.*/
#ifdef__USE_XOPEN
__fd_maskfds_bits[__FD_SETSIZE/__NFDBITS];
#define__FDS_BITS(set)((set)->fds_bits)
#else
__fd_mask__fds_bits[__FD_SETSIZE/__NFDBITS];
#define__FDS_BITS(set)((set)->__fds_bits)
#endif
}fd_set;

UNP学习第六章select的更多相关文章

  1. UNP学习第六章(二)

    一.描述符就绪条件 对于引起select返回套接字“就绪”的条件我们必须讨论得更明确: (1)满足一下塞个条件中的仍和一个时,一个套接字准备好读. a)该套接字接收缓冲区中的数据字节数不大于等于套接字 ...

  2. 201671010140. 2016-2017-2 《Java程序设计》java学习第六章

    java学习第六章    本周对与java中的接口,lambda表达式与内部类进行了学习,以下是我在学习中的一些体会:    1.接口: <1>.接口中的所有常量必须是public sta ...

  3. 【转载】Gradle学习 第六章:构建脚本基础

    转载地址:http://ask.android-studio.org/?/article/11 6.1. Projects and tasks 项目和任务Everything in Gradle si ...

  4. Java基础知识二次学习--第六章 常用类

    第六章 常用类   时间:2017年4月26日16:14:49~2017年4月26日16:56:02 章节:06章_01节~06章_06节 视频长度:20:57+1:15+8:44+1:26+11:2 ...

  5. C#高级编程 (第六版) 学习 第六章:运算符和类型强制转换

    第六章 运算符和类型强制转换 1,运算符 类别 运算符 算术运算符 + - * / % 逻辑运算符 & | ^ ~ && || ! 字符串连接运算符 + 增量和减量运算符 ++ ...

  6. 深度学习框架PyTorch一书的学习-第六章-实战指南

    参考:https://github.com/chenyuntc/pytorch-book/tree/v1.0/chapter6-实战指南 希望大家直接到上面的网址去查看代码,下面是本人的笔记 将上面地 ...

  7. UNP学习第13章 守护进程和inetd超级服务器

    Unix系统中的syslogd守护进程通常由某个系统初始化脚本启动,而且在系统工作期间一直运行. 源自Berkeley的syslogd实现在启动时执行以下步骤. (1)读取配置文件.通常为/etc/s ...

  8. UNP学习第五章(二)

    一.POSIX信号处理 信号:告知某进程发生了某个事件的通知(软中断),通常是异步的. 信号可以:由进程发给另一个进程,由内核发给某个进程. 设置信号处理办法,有三个选择: 1.写一个函数,在信号发生 ...

  9. UNP学习第三章

    一.主机字节序和网络字节序 转换时用到下列四个函数: #include <netinet/in.h> uint16_t htons(uint16_t host16bitvalue); ui ...

随机推荐

  1. visual studio code的使用

    1.添加代码片段 参考:https://blog.csdn.net/qq_36370731/article/details/83014439 2.在vscode上运行Git 先打开vscode内置的G ...

  2. Delphi界面篇之ListView控件

    //增加项或列(字段) ListView1.Clear; ListView1.Columns.Clear; ListView1.Columns.Add; ListView1.Columns.Add; ...

  3. 2018-2019 ACM-ICPC Brazil Subregional Programming Contest F. Music Festival

    题目:https://codeforces.com/gym/101908/problem/F 题意:给你n个舞台,每个舞台有很多个节目,每个节目有个开始时间,结束时间,价值,每个舞台至少出演过一个节目 ...

  4. dubbo漫谈二

    转:腾信视频 阿甘 https://ke.qq.com/course/216518 https://blog.csdn.net/u013142781/article/details/50396621 ...

  5. HTML段落,换行,字符实体

    HTML段落,换行,字符实体 html段落 <p>标签定义一个文本段落,一个段落含有默认的上下间距,段落之间会用这种默认间距隔开,代码如下: <!DOCTYPE html> & ...

  6. 一些关于SEO优化的笔记

    高级搜索指令: 双引号:“xxx” 代表完全匹配的搜索 减号:-(减号前面必须是空格,后面必须没有空格)代表搜索不包含减号后面的词的页面 filetype:用于搜索特定文件格式(百度支持的文件类型:P ...

  7. 转 awk统计nginx每天访问最高的接口

    TODAY=date +%d/%b/%Y 获取当天时间awk -v val="$TODAY" ’ $4 ~ val {print $7}’ access.log 打印当天访问的接口 ...

  8. 48-python基础-python3-字符串-常用字符串方法(六)-strip()-rstrip()-lstrip()

    7-用 strip().rstrip()和 lstrip()删除空白字符 strip()字符串方法将返回一个新的字符串,它的开头或末尾都没有空白字符. lstrip()和 rstrip()方法将相应删 ...

  9. Codeforces 492E Vanya and Field

    E. Vanya and Field time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  10. 在tkinter中使用matplotlib

    import sys import tkinter as Tk import matplotlib from numpy import arange, sin, pi from matplotlib. ...