IO多路复用机制

xiaoxiao2021-02-28  25

上篇文章讲到IO模式,这篇文章讲其中一种模式-IO多路复用模式。 IO多路复用技术根据实现不同,分为三种,select、poll、epoll。 1、select int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); select把监听的文件描述符分为3类,readfds、writefdds、exceptfds。 1.1 进程调用select后会阻塞 1.2 当有描述符就绪时,readfds可读或writefds可写或exceptfds有excpet或超时,函数返回 1.3 select返回后,通过遍历fdset,找到就绪的描述符 1.4 对就绪描述符进行读/写操作 2、poll int poll (struct pollfd *fds, unsigned int nfds, int timeout); struct pollfd {     int fd;        /* file descriptor */     short events;  /* requested events to watch */     short revents; /* returned events witnessed */ }; 和select不同之处在于, 2.1 poll用结构 pollfd来表示select中的三个fds 2.2 pollfd包括了要监视的时间和发生的时间,而select采用“参数-值”的传递方式 2.3 pollfd没有最大数量限制,而select有最大数量限制 3、epoll epoll用到三个接口 3.1  int epoll_create(int size); 3.1.1 epoll_create创建一个epoll监听句柄 3.1.2 参数size用来告诉内核这个epoll句柄监听的IO数目。 3.1.3 参数size并不是最大的监听数目,只是对内核初始化结构的建议。 3.2  int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); struct epoll_event {   __uint32_t events;  /* Epoll events */   epoll_data_t data;  /* User data variable */ }; //events可以是以下几个宏的集合: EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭); EPOLLOUT:表示对应的文件描述符可以写; EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来); EPOLLERR:表示对应的文件描述符发生错误; EPOLLHUP:表示对应的文件描述符被挂断; EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。 EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里 3.2.1 对epoll fd执行op操作 3.2.2 -epfd:epoll描述符,调用 epoll_create的返回值 3.2.3 -op:    添加EPOLL_CTL_ADD、删除EPOLL_CTL_DEL、修改EPOLL_CTL_MOD 3.2.4 -fd:  是需要监听的f文件描述符 3.2.5 -epoll_event:是告诉内核需要监听什么事 3.3 int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout); 3.3.1 等待epfd上的io事件,最多返回maxevents个事件。 3.3.2 参数events用来从内核得到事件的集合 3.3.3 maxevents告之内核这个events有多大,maxevents的值不能大于创建epoll_create()时的size, 3.3.4 参数timeout是超时时间(毫秒,0会立即返回,-1将不确定,也有说法说是永久阻塞)。 3.4 工作模式 3.4.1 水平触发模式(level trigger) 当epoll_wait检测到描述符事件发生并将此事件通知应用程序,应用程序可以不立即处理该事件。下次调用epoll_wait时,会再次响应应用程序并通知此事件。 3.4.2 边缘触发模式(edge trigger) 当epoll_wait检测到描述符事件发生并将此事件通知应用程序,应用程序必须立即处理该事件。如果不处理,下次调用epoll_wait时,不会再次响应应用程序并通知此事件
转载请注明原文地址: https://www.6miu.com/read-799993.html

最新回复(0)