#【I/O复用】
##-------------select-------------
#include <sys/select.h>
int select(nfds, //被监听的文件描述符的总数(最大文件描述符+1,因为文件描述符从0开始)
fd_set* readfds, //可读文件描述符的集合
fd_set* writefds,
fd_set* exceptfds,
struct timeval* timeout)
typedef struct{
long int bit_sets[1024/8/sizeof(long int)];
}fd_set;
struct timeval{
long tv_sec;
long tv_usec;
};
timeout = 0 则非阻塞
timeout = NULL 则阻塞
返回0 则在timeout时间内没有文件描述符就绪
返回-1 表示失败并设置errno
当被信号打断是设置errno=EINTR
返回>0 表示就绪的文件描述符
FD_ZERO(fd_set* fdset);
FD_SET(int fd,fd_set* fdset);
FD_CLR(int fd,fd_set* fdset);
FD_ISSET(int fd, fd_set* fdset);
##-------------poll-------------
#include <sys.poll.h>
int poll(struct pollfd* fds, //结构体数组首地址
nfds_t nfds, //数组大小
int timeout) //等待超时毫秒
struct pollfd{
int fd; //注册的文件描述符
short events; //关注的事件
short revents; //返回的事件,由内核填充
};
typedef unsigned long int nfds_t;
返回值同select
##-------------epoll-------------
epoll与select、poll不相同,他是liunx独有的,epoll把用户关心的事件集放入内核的事件表中,select需要每次传入文件描述符集、poll需要每次传入事件集,因此epoll比select、poll方便,但需要一个额外的文件描述符唯一的标识内核的事件表
#include <sys/epoll.h>
int epoll_create(int size);//size不起作用
返回文件描述符
int epoll_ctl(int epfd, //内核事件表的文件描述符
int op, //对fd的操作
int fd, //
struct epoll_event* event)//指定事件
op: EPOLL_CTL_ADD
EPOLL_CTL_MOD
EPOLL_CTL_DEL
struct epoll_event{
__uint32_t events; //epoll事件
epoll_data_t data; //用户数据
};
struct union epoll_data{
void* ptr;
int fd;
uint32_t u32;
uint64_t u64;
}epoll_data_t;
int epoll_wait(int epfd,
struct epoll_event* events, //输出事件数组
int maxevents, //监听的事件个数
int timeout)
返回就绪事件的个数,将就绪事件的从内核的事件描述表中复制到events中