文件描述符最多1024个,0stdin,1stdout,2stderro
IO多路复用
IO多路转接
1. 多个IO复用一个进程,不创建新进程和线程,效率高
2. 不适合处理比较耗时的任务
select
poll
epoll
1. 创建文件描述符集合
2. 添加文件描述符到集合中
3. 通知内核开始监测
4. 根据返回的结果做对应的操作(对io读、写操作)
应用场景:
1. 构建并发服务器,使用IO多路复用监测多个客户端套接字
2. 使用io多路复用监测多个IO所对应的通信(如:网络、串口、can....)
3. 在阻塞io中,进行超时监测
select:
1. 创建文件描述符集合 fd_set
2. 添加文件描述符到集合中 void FD_SET(int fd, fd_set *set);
3. 通知内核开始监测 select
4. 根据返回的结果做对应的操作(对io读、写操作)
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
功能:监测多路IO
参数:
nfds : 关注的文件描述符中的最大值+1
readfds:关注的读事件的文件描述符集合
writefds:关注的写事件的文件描述符结合
exceptfds:其他 异常
timeout : 超时时间,如果不设置:NULL
返回值:
成功:返回到达事件的个数
失败:-1
设置了超时时间:超时时间到达但没有事件,返回0
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);
epoll:
1. 创建文件描述符集合 int epoll_create(int size);
2. 添加文件描述符到集合中 epoll_ctl()
3. 通知内核开始监测 epoll_wait()
4. 根据返回的结果做对应的操作(对io读、写操作)
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
功能:
参数:
epfd:文件描述符集合句柄
op:
EPOLL_CTL_ADD: 向集合中添加文件描述符
EPOLL_CTL_MOD: 修改集合
EPOLL_CTL_DEL :删除文件描述符
fd :操作的文件描述符
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 */
};
event : EPOLLIN : 读操作
EPOLLOUT : 写事件
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
功能:监测IO事件
参数:
epfd : 文件描述符集合句柄
events : 保存到达事件的结合的首地址
maxevents : 监测时事件的个数
timeout:超时时间
-1 :不设置超时时间
返回值:
成功:返回到达事件的个数
失败:-1
设置超时:超时时间到达返回0