一、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. python使用qq邮箱向163邮箱发送邮件、附件

    在生成html测试报告后 import smtplib,time from email.mime.text import MIMEText from email.mime.multipart impo ...

  2. 4412 RS485

    一.485硬件原理 差分对传输数据的原理 IO数据的传输→差分对 rs232传输的距离在15米以下,RS485传输距离是几十米到1000米以上 为什么485可以传输这么远 差分对的机制可以降低电磁场的 ...

  3. LOJ 2997 「THUSCH 2017」巧克力——思路+随机化+斯坦纳树

    题目:https://loj.ac/problem/2977 想到斯坦纳树.但以为只能做 “包含一些点” 而不是 “包含一些颜色” .而且不太会处理中位数. 其实 “包含一些颜色” 用斯坦纳树做也和普 ...

  4. js中的$符

    js中的$代表什么意思呢? 首先js的作用是什么呢?是修饰网页动态内容的.那么修饰就需要定位主题,比如你把html比喻一个美女,让她唱一首歌.那么首先你要定位出是你想让哪个美女唱歌,通常我们用id来定 ...

  5. js另存为、打印、属性、加入收藏、关闭等代码

    js打开代码 <input name=Button onClick=document.all.WebBrowser.ExecWB(1,1) type=button value=打开> &l ...

  6. Linux(Ubuntu)常用命令(二)

    归档管理: 打包: tar -cvf xxx.tar 打包对象 (一般来说就是 -cvf 一起用)但这种不压缩的打包通常不用,接下来会说. -options:-c    生成档案文件,创建打包文件. ...

  7. Linux对用户态的动态内存管理

    Linux对内核态内存分配请求与用户态内存分配请求处理上分别对待 Linux本身信任自己,因此Linux内核请求分配多少内存,就会马上分配相同数量的内存出来. 但内核本身不相信应用程序,而且通常应用程 ...

  8. [USACO 07NOV]电话线Telephone Wire

    题目描述 Farmer John's cows are getting restless about their poor telephone service; they want FJ to rep ...

  9. 用select实现多客户端连接

    server.c 把accept也看成是一个read类型的函数, 于是我们可以把sockfd也放入到select中 maxi标记当前客户端连接数组的最大下标 select返回值为当前已经准备就绪的fd ...

  10. VS 2017产品秘钥

    Enterprise: NJVYC-BMHX2-G77MM-4XJMR-6Q8QF Professional: KBJFW-NXHK6-W4WJM-CRMQB-G3CDH