在C/S模型中服务器端需要同时处理多个客户端的连接请求,此时就需要使用多路复用
- 实现多路复用的最简单的方法是采用非阻塞方式套接字,服务器不断地查询各个套接字的状态,如果有数据到达则读出数据,如果没有数据到达则查看下一个端口。但是这样大量CPU的时间,效率非常低。
- 服务器进程并不主动地去询问套接字状态,而是向系统登记希望监视的套接字,然后阻塞。当套接字上有事发生时,系统通知服务器进程告知哪个套接字发生了什么事件,服务器进程查询对应套接字并进行处理。在这种工作方式下套接字上没有事件发生时,服务器进程不会去查询套接字的状态,从而不会浪费CPU时间,提高效率
函数:int select(int n,fd_set *readfds,fd_set *writefds,fd_set *exceptfd,struct timeval to)
- n # 是需要监视的文件描述符数,要监视的文件描述符值为0-------n-1
- readfds 指定需要监视的可读文件描述符的集合,当这个集合中的一个描述符上有数据到达时,系统将通知调用select函数的程序。
- writefds 指定需要监视饿可写文件描述符的集合,当这个集合中某个描述符可以发送数据时,程序将收到通知
- exceptfd 是需要监视的异常文件描述符集合,当该集合中的一个描述符发生异常时,程序将收到通知
- to指定了阻塞的时间,如果这段时间内监视的文件描述符上没有异常发生,那么select()将返回 0
文件描述符集合提高的宏操作
FD_CLR(int fd, fd_set *set) 将文件描述符fd从文件描述集合set中删除
FD_ISSET(int fd, fd_set *set) 测试fd是否在set中
FD_SET(int fd, fd_set *set) 在文件描述符集合中添加文件描述符fd
FD_ZERO(fd_set *set) 将文件描述符集合中set清空
函数:int poll(struct pollfd fds[], nfds_t nfds, int timeout)
poll()函数是某些unix系统提供的用于执行与select()函数同等功能的函数,但是效率比select()函
数高
- fds :是一个struct pollfd结构类型的数组,用于存放需要监测其状态的socket描述符;每当调用该函数之后,系统不会清空这个数组操作起来比较方便。而对于select函数来讲每次都会清空它所检测的socket 集合,导致每次调用select()之前需要将socket描述符重新加入到待检测的集合中。
- nfds:用于标记数组fds中的结构体元素的总数量。
- timeout:是poll函数调用阻塞的时间,单位:毫秒
函数 epoll 是LINUX内核为处理大批量句柄而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著程序程序在大量并发连接中只有少量活跃的情况下的系统cpu利用率。
阅读(1281) | 评论(0) | 转发(1) |