I/O复用(select,poll,epoll)的用法以及区别

select API

#include <sys/select.h>
int select(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,struct timeval *timeout);
#include <sys/select.h>
FD_ZERO(fd_set *fdset);
FD_SET(int fd,fd_set *fdset);
FD_CLR(int fd,fd_set *fdset);
int FD_ISSET(int fd,fd_set *fdset);
struct timeval
{
	long tv_sec;	//秒数
	long tv_usec;	//微秒数
}
#define __FD_SETSIZE 1024

1.如果timeout变量的tv_sec和tv_usec成员都为0,则select立即返回。
2.如果timeout传递NULL,则select将一直阻塞,直到某个文件描述符就绪。
3。select成功时返回就绪的文件描述符的总数,如果在超时时间内没有任何文件描述符就绪,select返回0. select失败时返回-1并设置errno,如果在select等待期间,程序收到信号,则select立即返回-1,并设置errno为EINTER。


poll API

#include <poll.h>
int poll(struct pollfd *fds,nfds_t nfds,int timeout);

1.fds参数是一个pollfd类型的结构体,它指定所有我们感兴趣的文件描述符上发生的可读,可写和异常事件。
2.nfds参数指定被监听的事件集合fds的大小,

typedef unsigned long int nfds_t;

3.timeout参数指定poll的超时值,单位是毫秒,当timeout为-1时,poll调用将永远阻塞,直到某个事件发生,当timeout为0时,poll调用将立刻返回

struct pollfd
{
	int fd;	//文件描述符
	short events;	//注册的事件
	short revents;	//实际发生的事件,由内核填充
}

fd成员指定文件描述符,events成员告诉poll监听fd上的哪些事件,revents成员由内核修改,以通告应用程序fd上实际发生了哪些事件

POLLIN 数据可读
POLLOUT 数据可写
POLLERR 错误

epoll API

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

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

int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout);

1.size参数现在不起作用,只是给内核一个提示。
2.fd是参数要操作的文件描述符,op参数则指定操作类型

EPOLL_CTL_ADD 往事件表中添加fd上的事件
EPOLL_CTL_MOD 修改fd上的注册事件
EPOLL_CTL_DEL 删除fd上的注册事件

3.epoll_ctl成功时返回0,失败时返回-1
4.epoll_wait成功时返回就绪的文件描述符个数,失败时返回-1
5.epoll_wait函数如果检测到事件,将所有的就绪的事件从内核事件表中复制到它的第二参数events指向的数组,这个数组只用于输出epoll_wait检测到的就绪事件。

struct epoll_event
{
	__uint32_t events;	//epoll事件
	epoll_data_t data;	//用户数据
};
typedef union epoll_data
{
	void *ptr;
	int fd;
	uint32_t u32;
	uint64_t u64;
}epoll_data_t;

poll和epoll在使用上的差别

int ret=poll(fds,MAX_EVENT_NUMBER,-1);
for(int o=0;i<MAX_EVENT_NUMBER;i++)
{
	if(fds[i].revents & POLLIN)
	{
		int sockfd=fds[i].fd;
		/*处理sockfd*/
	}
}

int ret=epoll_wait(epollfd,events,MAX_EVENT_NUMBER,-1);
for(int i=0;i<ret;i++)
{
	int sockfd=events[i].data.fd;
	/*sockfd肯定就绪,直接处理*/
}

LT模式以及ET模式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三组IO复用的比较

在这里插入图片描述
在这里插入图片描述

发布了46 篇原创文章 · 获赞 0 · 访问量 431

猜你喜欢

转载自blog.csdn.net/weixin_42226134/article/details/104394562