本篇内容介绍了“linux要用select的原因是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
公司主营业务:成都网站制作、成都做网站、外贸营销网站建设、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。成都创新互联公司是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。成都创新互联公司推出正镶白免费做网站回馈大家。
因为select可以使开发者在同时等待多个文件缓冲区,可减少IO等待的时间,能够提高进程的IO效率。select()函数是IO多路复用的函数,允许程序监视多个文件描述符,等待所监视的一个或者多个文件描述符变为“准备好”的状态;所谓的”准备好“状态是指:文件描述符不再是阻塞状态,可以用于某类IO操作了,包括可读,可写,发生异常三种。
select是一个计算机函数,位于头文件#include
select函数是IO多路复用的函数,它主要的功能是用来等文件描述符中的事件是否就绪,select可以使我们在同时等待多个文件缓冲区 ,减少IO等待的时间,能够提高进程的IO效率。
select()函数允许程序监视多个文件描述符,等待所监视的一个或者多个文件描述符变为“准备好”的状态。所谓的”准备好“状态是指:文件描述符不再是阻塞状态,可以用于某类IO操作了,包括可读,可写,发生异常三种
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
等待的文件描述符的最大值+1,例如:应用进程想要去等待文件描述符3,5,8的事件,则
nfds=max(3,5,8)+1;
readfds和writefds,exceptfds的类型都是fd_set,那么fd_set类型是什么呢?
fd_set类型本质是一个位图,位图的位置 表示 相对应的文件描述符,内容表示该文件描述符是否有效,1代表该位置的文件描述符有效,0则表示该位置的文件描述符无效。
如果将文件描述符2,3设置位图当中,则位图表示的是为1100。
fd_set的上限是1024个文件描述符。
readfds是 等待读事件的文件描述符集合,.如果不关心读事件(缓冲区有数据),则可以传NULL值。
应用进程和内核都可以设置readfds,应用进程设置readfds是为了通知内核去等待readfds中的文件描述符的读事件.而 内核设置readfds是为了告诉应用进程哪些读事件生效
与readfds类似,writefds是等待写事件(缓冲区中是否有空间)的集合,如果不关心写事件,则可以传值NULL。
如果内核等待相应的文件描述符发生异常,则将失败的文件描述符设置进exceptfds中,如果不关心错误事件,可以传值NULL。
设置select在内核中阻塞的时间,如果想要设置为非阻塞,则设置为NULL。如果想让select阻塞5秒,则将创建一个struct timeval time={5,0};
其中struct timeval的结构体类型是:
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
如果没有文件描述符就绪就返回0;
如果调用失败返回-1;
如果timeout中中readfds中有事件发生,则返回timeout剩下的时间。
应用进程和内核都需要从readfds和writefds获取信息,其中,内核需要从readfds和writefds知道哪些文件描述符需要等待,应用进程需要从readfds和writefds中知道哪些文件描述符的事件就绪.
如果我们要不断轮询等待文件描述符,则应用进程需要不断的重新设置readfds和writefds,因为每一次调用select,内核会修改readfds和writefds,所以我们需要在 应用程序中 设置一个数组来保存程序需要等待的文件描述符,保证调用 select 的时候readfds 和 writefds中的将如下:
如果是一个select服务器进程,则服务器进程会不断的接收有新链接,每个链接对应一个文件描述符,如果想要我们的服务器能够同时等待多个链接的数据的到来,我们监听套接字listen_sock读取新链接的时候,我们需要将新链接的文件描述符保存到read_arrys数组中,下次轮询检测的就会将新链接的文件描述符设置进readfds中,如果有链接关闭,则将相对应的文件描述符从read_arrys数组中拿走。
一张图看懂select服务器:
简易版的select服务器:
server.hpp文件:
#pragma once
#include
select_server.hpp文件
#pragma once
#include
select_server.cc文件
#include"select_server.hpp"
int main(int argv,char* argc[]){
if(argv!=2){
cout<<"./selectserver port"<
测试:
由于fd_set的上限是1024,所以select能等待的读事件的文件描述符和写事件的文件描述是有上限的,如果作为一个大型服务器,能够同时链接的客户端是远远不够的。
每次应用进程调用一次select之前,都需要重新设定writefds和readfds,如果进行轮询调用select,这对影响cpu效率。
内核每一次等待文件描述符 都会重新扫描所有readfds或者writefds中的所有文件描述符,如果有较多的文件描述符,则会影响效率。
“linux要用select的原因是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!