一、poll
基本原理与select一致, 也是轮询+遍历;唯一的区别就是poll没有最大文件描述符限制(使用链表的方式存储fd)
原型:int poll(struct pollfd *fds, nfds_t nfds, int time out);
POLLIN可读
POLLPUT可写
POLLERR异常
nfds:数组个数
timeout:延迟时间
#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <sys/stat.h> #include <poll.h> int main(int argc, char const *argv[]) { int fd; if((fd = open("/dev/input/mouse0", O_RDWR | O_CREAT, 0655)) < 0) { perror("open file error!"); exit(1); } struct pollfd fds[2]; fds[0].fd = 0; fds[0].events = POLLIN; fds[1].fd = fd; fds[1].events = POLLIN; while(1) { int ret = poll(fds, 2, -1); for (size_t i = 0; i < 2; i++) { if (fds[i].events == fds[i].revents) { if (fds[i].fd == 0) { char buffer[1024]; read(fds[i].fd, buffer, sizeof(buffer)); printf("buffer = %s\n",buffer); } else if (fds[i].fd == fd) { int cor; read(fds[i].fd, &cor, sizeof(cor)); printf("cor = %d\n", cor); } if (--ret == 0) { break; } } } } return 0; }
二、epoll
自学
select内部使用数组实现,poll是链表。他们需要做内核区到用户区的转换,还需要做数据拷贝,因此效率低。
epoll不需要做内核区到用户区的转换。因为数据存在共享内存中。epoll维护的树在共享内存中,epqJ维护的树在共享内存中,内核区和用户区去操作共享内存,因此不需要区域转换,也不需要
三、异步IO
进程和网络时再讲,select也算异步,但是有阻塞,一旦阻塞就是同步