Linux |
您所在的位置:网站首页 › linux特有的io多路复用 › Linux |
一、为什么需要?
看上一篇文章 二、基本思想
#先构造一张有关描述符的表,然后调用一个函数,这些文件描述符的一个或者多个已准备好进行IO操作时的函数才返回;
函数返回时告诉进程那个描述符已就绪,可以进行IO操作。 三、select函数大部分Unix/Linux都支持select函数,该函数用于探测多个文件句柄的状态变化。 1.头文件 #include #include #include 2.函数体 int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout); 3.参数
nfds:最大的文件描述符+1
readfds:读事件的表
writefds:写事件的表
exceptfds:异常事件的表
timeout:超时检测 //填NULL表示一直阻塞,直到文件描述符准备好为止 4.宏选项 用于设置文件描述符 void FD_CLR(int fd, fd_set *set);//把表中的一个文件描述符删除 int FD_ISSET(int fd, fd_set *set);//检测文件描述符是否准备好了,准备好了返回1,否则返回0 void FD_SET(int fd, fd_set *set);//加入到表中 void FD_ZERO(fd_set *set);//清空表5.返回值 成功:准备好的文件描述符个数 失败:-1; 6.优缺点分析
select基本原理: 首先创建一张文件描述符表(fd_set),通过使用特有的函数(select),让内核帮助上层用户循环检测是否有可操作的文件描述符,如果有则告诉应用程序去操作。 在多路复用IO模型中,会有一个线程不断去轮询多个socket的状态,只有当socket真 正有读写事件时,才真正调用实际的IO读写操作。因为在多路复用IO模型中,只需要使用 一个线程就可以管理多个 socket,系统不需要建立新的进程或者线程,也不必维护这些线 程和进程,并且只有在真正有socket读写事件进行时,才会使用IO资源,所以它大大减少 了资源占用。 从流程上来看,使用select函数进行IO请求和同步阻塞模型没有太大的区别,甚至还 多了添加监视socket,以及调用select函数的额外操作,效率更差。但是,使用select以后 最大的优势是用户可以在一个线程内同时处理多个socket的IO请求。用户可以注册多个 socket,然后不断地调用select读取被激活的socket,即可达到在同一个线程内同时处理多 个IO请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的。 这种模型的特征在于每一个执行周期都会探测一次或一组事件,一个特定的事件会触 发某个特定的响应。我们可以将这种模型归类为“事件驱动模型”。相比其他模型,使用select的事 件驱动模型只用单线程(进程)执行,占用资源少,不消耗太多CPU,同时能够为多客户端提供服务。 如果试图建立一个简单的事件驱动的服务器程序,这个模型有一定的参考价值。 但这个模型依旧有着很多问题: 当需要探测的句柄值较大时,select()接口本身需要消耗大量时间去轮询各个句柄;该模型将事件 探测和事件响应夹杂在一起,一旦事件响应的执行体庞大,那么就会导 致后续的事件迟迟得不到处理,并且会影响新的事件轮询,在很大程度上降低了事件探测的及时性。 所以select机制只适用于"短作业" 处理机制. (处理时间短) 实例代码: 案例一: 利用复用IO,简单解决对多个管道进行写操作时阻塞的问题 #include #include #include #include #include #include #include #include int main(int argc, const char *argv[]) { int fd1 = open("./f1", O_RDWR); int fd2 = open("./f2", O_RDWR); int fd3 = open("./f3", O_RDWR); //1.创建一张文件描述符表 fd_set readfds, tmpfds; FD_ZERO(&readfds); //2.清空表 FD_SET(fd1, &readfds); FD_SET(fd2, &readfds); FD_SET(fd3, &readfds); int maxfd = fd3; tmpfds = readfds; char buf[64] = {0}; int ret, i; while(1) { readfds = tmpfds; ret = select(maxfd+1, &readfds, NULL, NULL,NULL); if(ret == -1) { perror("select"); return -1; } for(i=fd1; i |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |