精通epoll架构数组
epoll:Linux中最优秀的多路复用机制!架构
与select 、poll区别函数
1.select和poll没有太大区别,除了select有文件描述符限制(1024个)。select每次调用都须要将fd集合拷贝到内核态,且监听过程遍历全部的文件位置,开销很大。spa
2.Epoll监测无上限,在注册新事件时就会一次性把全部fd拷贝到内核,无序遍历便可查询到监听位置,提升效率。code
优点:1)多路复用; 2)阻塞IO; 3)无需遍历全部文件便可知道错误的文件位置(高效) 4)监控文件无上限视频
多路复用:一个进程同时监控多个文件或设备;blog
阻塞IO :进程执行过程当中,无命令处理时进程休眠,有命令待处理时,唤醒进程处理命令;(避免在无命令时进程忙等占用CPU,高效)队列
epoll支持管道FIFO、套接字socket、POSIX消息队列、终端等,但不支持普通文件。epoll分红以下三个环节:进程
建立epoll监听池 | epfd = epoll_create(50) 返回epfd指向建立的监听池 |
添加epoll监听事件 | epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event) 事件 监听池epfd 操做符 要监听文件的fd 监听结构类型 |
等待监听事件发生 | n = epoll_wait(epfd, events, 100, -1) 返回事件发生个数 |
int main() { int fd1,fd2,efd; struct epoll_event event; struct epoll_event *events; // 建立FIFO
mkfifo("/tmp/fifo1",0666); //要建立的FIFO文件的名字(含路径)
mkfifo("/tmp/fifo2",0666); fd1=open("/tmp/fifo1",O_RDONLY); //打开管道文件监听
fd2=open("/tmp/fifo2",O_RDONLY); //1. 建立监听池
efd = epoll_create1(0); //2. 构造监听事件,加入监听池
event.events = EPOLLIN|EPOLLET; //可读 边沿触发
event.data.fd = fd1; //关注的文件
epoll_ctl(efd,EPOLL_CTL_ADD,fd1,&event); /* 分别两管道构造 */
event.events = EPOLLIN|EPOLLET; //可读
event.data.fd = fd2; //关注的文件
epoll_ctl(efd,EPOLL_CTL_ADD,fd2,&event); //添加事件到监听池 //3. 等待事件的发生
events = calloc(100,sizeof event); //保存事件的数组
n=epoll_wait(efd,events,100,-1); for(i=0;i<n;i++) { if(events[i].events&EPOLLIN) { read(events[i].data.fd,&c,1); printf("file %d can be read\n",events[i].data.fd); } } free(events); close(fd1); close(fd2);//关闭打开的文件+释放申请的堆内存 }
检测:分别编写程序,向两个管道文件内写入数据,编译运行 -> epoll当即检测到事件发生。
----------------------------------------------------------------------------------------------------------
epoll架构加入摄像头采集端,监听摄像头是否采集到数据(应用用途)
建立基本的监听架构,将摄像头采集端做为监听事件,添加至监听池,当监听到摄像头捕捉到图像文件时,即自动触发启动对应的处理函数,将获取到图片数据发送至显示子系统,添加移植至GTK程序便可实现视频采集播放。