Linux-C网络编程之select函数
来源:互联网 发布:网络语gg是什么意思 编辑:程序博客网 时间:2024/05/22 09:04
开门见山,如果我们要对多个客户端连接的多个事件进行操作,首先会想到建立多个线程或进程让其去各自进行,这也是最简单的模式。
但对每一个线程或进程而言,无论连接是否有事件发生,都必须随时待命,也就是说,每一个对象都必须有一个线程或进程与之一一对应,直到对象销毁。
可想而知,当连接量规模变大后,系统需要在很多个线程或进程之间进行切换,时间与空间上的开销巨大,也就是说,这种模式下,程序能承载对象的最大值是很小的(一般数百个)。
那么,就要提到select函数了。man select得到函数参数及头文件如下
#include <sys/select.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); void FD_CLR(int fd, fd_set *set);//删除fd int FD_ISSET(int fd, fd_set *set);//检测fd是否存在于组 void FD_SET(int fd, fd_set *set);//添加fd void FD_ZERO(fd_set *set);//对组进行清零
nfds:整型变量,是指集合中所有文件描述符的范围,假如集合中最大文件描述符为max,那么 ndfs=max+1,千万不要理解为文件描述符的总量。
readfds:指针,指向一组等待可读性检查的套接字集合。
writefds:指针,指向一组等待可写性检查的套接集合。
exceptfds:指针,指向一组等待错误检查的套接集合。
timeout:select()最多等待时间,如果为NULL,则相当于阻塞(等待直到事件发生),若为 0 则为非阻塞(没有事件便立即返回),其他值代表若有事件或是超时则返回。
函数流程解释及样例
int ret,i,fd[MAX],MAX; struct timeval timeout; fd_set readfds; while(1) { timeout.tv_sec = 1; timeout.tv_usec = 0; FD_ZERO(&readfds);//组清零初始化 for(i=0;i<MAX;i++) { FD_SET(fd[i], &readfds); } ret select(MAX,&readfds, NULL,NULL,&timeout);//仅演示读监听,其他同理 }
将select放在循环体内时,有两点是要特别注意的
<1>timeout的初始化,因为select在执行时,对timeout进行的实际是类似于i–的操作,所以循环体内每次都要重新初始化,否则timeout的值将永久是0;
<2>文件描述符集合的初始化,因为集合的机理类似于二进制,FD_ZERO()后集合内全部归零(0000000),若FD_SET(5),则为(0100000),当selete在执行过程中,发现每个某个连接有事件产生时,便会将该套接字标志为1,没有事件的标志为0,执行完成后,若有事件产生,则可以FD_ISSET(fd,&readfds)来判断fd是否有事件产生。
因此,每执行一次select函数,都要重新对集合进行初始化。
select()可以确定一个或多个套接口的状态,常用来实现单进程或单线程的多路复用。
也就是说,select可以在一个线程或进程内对多个连接的事件事件进行响应。
那么它是如何完成这个功能的呢,举个例子来说:
假如你在100家不同的店各订了一份外卖(不同的店收货点当然是不同的)。
- 如果用上述多进程或线程的模式来取外卖的话,你就要再找99个朋友帮你去各个收货点去等待。(多进程模式,哪来的手机!)
- 你有一盏名叫select的信号灯,你只需要守候在select前,每当一家或多家外卖要送到的时候,都会将信号灯点亮,那么问题来了,你只知道外卖送到了,但却并不知道到底是哪家,所以你需要亲自把100家外卖的送货点全部遍历一遍,取下已到的外卖,然后继续回到信号灯前等待。有什么优点呢,很显然,100个人才能完成的事你一个人就完成了,而且多个外卖可能会同时到,顺风路走了不少嘛。
至于缺点嘛,当然是每次都要把100家收货点全部走一遍(减肥也没有这么拼的)- 找epoll函数,它会给你一部手机,送货师傅外卖送到时可以给你打电话啦。有了手机,这一切该是多么完美,那么会是怎么个完美法呢,下章再谈吧。
ps:好困啊,年纪大了,熬不了夜了!
- Linux-C网络编程之select函数
- linux网络编程 select()函数
- Linux网络编程之select
- linux网络编程之select
- linux c/c++网络编程之—select模型
- Linux-C网络编程之epoll函数
- linux 网络编程 select函数用法
- Linux网络编程(4):select函数
- Linux网络编程(4):select函数
- Linux网络编程(五) select函数
- Linux网络编程--select()和pselect()函数
- Linux 网络编程中的 select 函数
- linux c/c++网络编程----select模型
- linux网络编程之 select()的模型
- linux网络编程之 select()的模型
- Linux 网络编程之socket、select
- linux socket网络编程之select
- linux网络编程之select模型
- A. Lineland Mail-水题-Codeforces Round #Pi (Div. 2)
- B. Berland National Library-水题- Codeforces Round #Pi (Div. 2)
- JAVA学习笔记(二)
- 虚拟机中的Ubuntu14.04启动时自动设置分辨率为1920x1080
- CF-567C - Geometric Progression
- Linux-C网络编程之select函数
- 科技湃|推特移动端内测新闻功能,对媒体是不是好事?
- Android 应用开发相关下载资源(2015/05/06更新)
- C语言的表达式与语句
- SAP各模块介绍
- Node.js开发入门—HTTP文件服务器
- 软件开发方法
- python基础学习笔记
- Android将Activity打成jar包供第三方调用(解决资源文件不能打包的问题)