加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码网 (https://www.900php.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Unix > 正文

UNIX环境高级编程:select和epoll的区别

发布时间:2016-07-28 15:33:27 所属栏目:Unix 来源:站长网
导读:select和epoll都用于监听套接口描述字上是否有事件发生,实现I/O复用 select(轮询) #include sys/select.h #include sys/time.h int select (int maxfdpl, fd_set* readset, fd_set* writeset, fd_set* exceptset, const struct timeval* timeout) 调用

select和epoll都用于监听套接口描述字上是否有事件发生,实现I/O复用

select(轮询)

#include <sys/select.h>  
#include <sys/time.h>  
int select (int maxfdpl, fd_set* readset, fd_set* writeset, fd_set* exceptset, const struct timeval* timeout)

调用时轮询一次所有描述字,超时时再轮询一次。如果没有描述字准备好,则返回0;中途错误返回-1;有描述字准备好,则将其对应位置为1,其他描述字置为0,返回准备好的描述字个数。

fd_set:整数数组,每个数中的每一位对应一个描述字,其具体大小有内核的FD_SETSIZE(1024)决定。

void FD_ZERO(fd_set* fdset);//clear all bits in fdset  
void FD_SET(int fd, fd_set* fdset);//turn on the bit for fd in fdset  
void FD_CLR(int fd, fd_set* fdset);//turn off the bit for fd in fdset  
int FD_ISSET(int fd, fd_set* fdset);//is the bit for fd on in fdset

epoll(触发)

epoll对监听的每个fd都会有回调函数,当该fd上发生事件时,会调用对应的回调函数。

系列函数:

创建函数:

创建一个epoll句柄,size-监听套接字的数。当创建好epoll句柄后,会占用一个fd值,所以在使用完epoll后,必须调用close()关闭,否则可能导致fd被耗尽。

#include <sys/epoll.h>  
int epoll_create(int size);

事件注册函数:

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);  

第一个参数是epoll_create()的返回值;
第二个参数表示动作,用三个宏来表示:
EPOLL_CTL_ADD:注册新的fd到epfd中,
EPOLL_CTL_MOD:修改已经注册的fd的监听事件,
EPOLL_CTL_DEL:从epfd中删除一个fd;
第三个参数是需要监听的fd;
第四个参数是告诉内核监听事件,struct epoll_event结构如下:

typedef union epoll_data {   
void *ptr;   
int fd;   
__uint32_t u32;   
__uint64_t u64;   
} epoll_data_t;   
      
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队列里

使用如下:

struct epoll_event ev;   
ev.data.fd=listenfd;  
ev.events=EPOLLIN|EPOLLET;   
epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);

(编辑:源码网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读