I/O复用:select和poll函数

I/O复用典型使用在下列网络应用场合:

  • 当客户处理多个描述符(通常是交互式输入和网络套接字)时,必须使用I/O复用。
  • 如果一个TCP服务器既要处理监听套接字,又要处理已连接套接字,一般就要使用I/O复用。
  • 如果一个服务器既要处理TCP,又要处理UDP,一般要使用I/O复用。
  • 如果一个服务器要处理多个服务或者多个协议(如inetd守护进程),一般要使用I/O复用。

I/O模型

Unix下可用的5种I/O模型基本区别:

  1. 阻塞式I/O
  2. 非阻塞式I/O
  3. I/O复用(select和poll)
  4. 信号驱动式I/O(SIGIO)
  5. 异步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
}

这个参数有以下三种可能:

  1. 永远等待下去:仅在有一个描述符准备好I/O时才返回,为此,可设置为空指针
  2. 等待一段固定的时间:在有一个描述符准备好I/O时返回,但是不超过由该参数所指向的timeval结构中指定的秒数和微秒数。
  3. 根本不等待:检查描述符后立即返回,这称为轮询。为此,该参数必须指向一个timeval结构,而且其中的定时器值(由timeval结构指定)必须为0。

猜你喜欢

转载自blog.csdn.net/weixin_37160123/article/details/90142061