Linux企业级项目实践之网络爬虫(27)——多路IO复用

与多线程和多进程相比,I/O多路复用的最大优势是系统开销小,系统不需要建立新的进程或者线程,也不必维护这些线程和进程。

主要应用:

(1)客户程序需要同时处理交互式的输入和服务器之间的网络连接

(2)客户端需要对多个网络连接作出反应

(3)TCP服务器需要同时处理多个处于监听状态和多个连接状态的套接字

(4)服务器需要处理多个网络协议的套接字

(5)服务器需要同时处理不同的网络服务和协议

 select()函数

#include <sys/time.h>
int select(int nfds, fd_set *readfds,fd_set *wtitefds, fd_set *errnofds,
struct timeval *timeout)

注意:描述符不受限与套接字,任何描述符都行

nfds:select()函数监视的描述符数的最大值,一般取监视的描述符数的最大值+1,

其上限设置在sys/types.h中有定义

#define FD_SETSIZE 256

readfds:select()函数监视的可读描述符集合

wtitefds:select()函数监视的可写描述符集合

errnofds:select()函数监视的异常描述符集合

timeout:select()函数监视超时结束时间,取NULL表示永久等待

timeout告知内核等待所指定描述字中的任何一个就绪可花多少时间。其timeval结构用于指定这段时间的秒数和微秒数。

        struct timeval{
                   long tv_sec;   //seconds
                   long tv_usec;  //microseconds
      };

这个参数有三种可能:

(1)永远等待下去:仅在有一个描述字准备好I/O时才返回。为此,把该参数设置为空指针NULL。

(2)等待一段固定时间:在有一个描述字准备好I/O时返回,但是不超过由该参数所指向的timeval结构中指定的秒数和微秒数。

(3)根本不等待:检查描述字后立即返回,这称为轮询。为此,该参数必须指向一个timeval结构,而且其中的定时器值必须为0。

返回值:返回总的位数这些位对应已准备好的描述符,否则返回-1

相关宏操作:

      FD_ZERO(fd_set *fdset):清空fdset与所有描述符的关系
      FD_SET(int fd, d_set * fdset):建立描述符fd与fdset得关系
      FD_CLR(int fd, d_set * fdset):撤销描述符fd与fdset得关系
      FD_ISSET(int fd, d_set * fdset):检查与fdset联系的描述符fd是否可以读写,返回非零表示可以读写


 select()函数实现IO多路复用的步骤

(1)清空描述符集合

(2)建立需要监视的描述符与描述符集合的关系

(3)调用select函数

(4)检查监视的描述符判断是否已经准备好

(5)对已经准备好的描述符进程IO操作

原文地址:https://www.cnblogs.com/new0801/p/6176981.html