其实linux自带的man是非常好的学习工具。
select, poll, epoll都能直接通过man得到很详细的解释,当然具体的栗子就需要在网上找找或者看看书了。
1.select
#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
void FD_CLR(int fd, fd_set *set);
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);
需要注意的就是
①fd_set就是用于需要监听的描述符的句柄的集合,是一个专门的数据结构
②这里面的*都是需要在填参数的时候取地址的意思
③select(套接字最大数+1, 读描述符, 写描述符, 异常描述符, 超时时间)
④返回值,0表示超时返回,正数表示监听事件发生的数量,负数表示异常。
2.poll
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
struct pollfd{
int fd;
short events;
short revents;
};
需要注意的就是
①struct pollfd表示的是一个结构体。对比与select,poll中将套接字描述符与关注的具体事件分隔开来了。
因此fd就只是关注的fd,而关注的事件具体是可读还是可写,就是events的事情了,
并且具体某套接字发生了什么事件,是通过revents来返回。
②具体的关注事件
可读POLLIN==POLLRDNORM
可写POLLOUT==POLLWRNORM
③参数里面的struct pollfd *fds,这个*表示的是fds是一个数组名
通过将所要关注的描述符,以及该描述符上面的事件放入一个结构体,
再将结构体放入它的数组,就能监听一系列事情了。
这样就完全是以不同的描述符为单个个体了,而不必像select一样,同一个描述符上面的不同事件还需放入两个集合。
3.epoll
#include <sys/epoll.h>
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, sturct epoll_event *event);
int epoll_wait(int epfd, sturct epoll_event *events, int maxevents, int timeout);
struct epoll_event{
unit32_t events;
epoll_data_t data;
}
typedef union epoll_data{
void *ptr;
int fd;
unit32_t u32;
unit64_t u64;
} epoll_data_t;
需要注意的就是
①epoll_create参数size只要填写一个>0的整数即可,返回一个epoll描述符epfd,用于代表整个epoll
②epoll_ctl(epoll描述符, 将监听描述符加入/改变/注销监听, 需要监听的描述符, 需要关心的事件及其绑定的描述符(*表示取结构体的地址))
③epoll_wait(epoll描述符, 用于存放返回事件及其对应描述符的结构体数组, 最大事件数量, 超时时间)
本文详细介绍了 Linux 下的 I/O 多路复用技术 select、poll 和 epoll 的使用方法及特点。通过对比这三种技术,帮助读者理解它们之间的区别与联系,并指导如何根据实际需求选择合适的方法。

被折叠的 条评论
为什么被折叠?



