I/O复用典型使用在下列网络应用场合:
- 当客户处理多个描述符(通常是交互式输入和网络套接字)时,必须使用I/O复用。
- 如果一个TCP服务器既要处理监听套接字,又要处理已连接套接字,一般就要使用I/O复用。
- 如果一个服务器既要处理TCP,又要处理UDP,一般要使用I/O复用。
- 如果一个服务器要处理多个服务或者多个协议(如inetd守护进程),一般要使用I/O复用。
I/O模型
Unix下可用的5种I/O模型基本区别:
- 阻塞式I/O
- 非阻塞式I/O
- I/O复用(select和poll)
- 信号驱动式I/O(SIGIO)
- 异步I/O(POSIX的aio_系列函数)
阻塞式I/O
非阻塞式I/O模型
I/O复用模型
信号驱动式I/O模型
首先开启套接字的信号驱动式I/O功能,并通过sigaction系统调用安装一个信号处理函数。该系统调用将立即返回,我们进程继续工作,也就是说它没有被阻塞。当数据报准备好读取时,内核就为该进程产生一个SIGIO信号。我们随后既可以在信号处理函数中调用recvfrom读取数据报,并通知主循环数据已准备好待处理,也可以立即通知主循环,让它读取数据报。
异步I/O模型
一般的,该模型夏啊的函数工作机制是:告知内核启动某个操作,并让内核在整个操作(包括将数据从内核复制到我们自己的缓冲区)完成后通知我们。这种模型与信号驱动模型的主要区别紫玉:信号驱动式I/O是由内核通知我们何时可以启动一个I/O操作,而异步I/O模型是由内核通知我们I/O操作何时完成。
扫描二维码关注公众号,回复:
6214426 查看本文章
select函数
该函数允许进程指示内核等待多个事件中的任何一个发生,并只在有一个或多个事件发生或经历一段指定的时间后才唤醒它。
#include<sys/select.h>
#include<sys/time.h>
//返回:若有就绪描述符则为其数目,若超时则为0,若出错则为-1
int select(int mxfdpl,fd_set *readset,fd_set *writeset,fd_set *exceptset,\
const struct timevla *timeout)
参数解析:
1、timeout:告知内核等待所指定描述符中的任何一个就绪可花多长时间,其timeval结构用于指定这段时间的秒数和微妙数。
struct timeval{
long tv_sec; //seconds
long tv_usec; //microseconds
}
这个参数有以下三种可能:
- 永远等待下去:仅在有一个描述符准备好I/O时才返回,为此,可设置为空指针。
- 等待一段固定的时间:在有一个描述符准备好I/O时返回,但是不超过由该参数所指向的timeval结构中指定的秒数和微秒数。
- 根本不等待:检查描述符后立即返回,这称为轮询。为此,该参数必须指向一个timeval结构,而且其中的定时器值(由timeval结构指定)必须为0。