快速业务通道

Linux事件监控机制遗漏事件问题的相关分析

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-04-19

  目前比较通用的监控Linux下文件系统变化的是Epoll iNotify结合的机制.

  Epoll有两种机制,LevelTrigger和EdgeTrigger, 前者相当于fast poll, 后者可以理解为对nonblocking fd的阻塞化, 这个说法严格来讲有点儿业余,只是为了简单的说明问题.

  对于从epoll_wait等待事件触发,然后进行read.这里做下说明,在读事件的时候, Linux下的epoll是异步读,而Windows下的IOCP是同步读,从后面的分析可以发现,同步读似乎更有优势.

  开始的时候,对于wait事件发生并进行read的线程,并没有提高其优先级,发现在过于频繁的往目录下添加文件和目录的时候,会丢事件.这样在做实时同步时,要想办法弥补丢失的事件.

  第一个方案是对新添加的目录,先把目录add_watch,然后把该目录扫描一遍.add_watch只是为了确保新建目录被加入watch,一般不会漏掉的,除非是在事件被漏掉的情况下.漏掉指的是在目录新建并上报到加入watch前的这段时间,在该目录下又发生了新建文件或目录时,会漏事件. iNotify是允许对同一个目录add_watch两遍的,但是add时还要访问硬盘,确保目录存在才能添加,做了一个缓存,path<--->wd,通过path的查找确定是否已add_watch,若没add再add下.

  第一个方案里漏事件的问题通过事后扫描得到解决,但是再扫描一遍是否有意义呢? 分析了Linux的线程有限级和调度策略之后,发现实时优先级有两种SCHED_FIFO和SCHED_RR.从Linux kernel development里chapter4 RealTime看到:

  “SCHED_RR is identical to SCHED_FIFO except that each process can run only until it exhausts a predetermined timeslice. That is, SCHED_RR is SCHED_FIFO with timeslicesit is a real-time round-robin scheduling algorithm. When a SCHED_RR task exhausts its timeslice, any other real-time processes at its priority are scheduled round robin. The timeslice is used only to allow rescheduling of same-priority processes.”

  这也就是说,若是把读事件的线程设置为FIFO,则没有timeslice的限制,可以直到读完事件,并且不会被抢占;而用RR则在timeslice用完一个之后,就会调度到别的线程,觉得可以用FIFO的设置来替代低效的扫描.

  注1:

  设置线程策略可以用下面的api:

  1.pthread_attr_getschedpolicy(const pthread_attr_t *restrict attr, int *restrict policy); 拥有帝国一切,皆有可能。欢迎访问phome.net

  2.pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy );

  设置线程优先级可以用下面的api:

  1.int sched_get_priority_max(int policy);

  2.int sched_get_priority_min(int policy);

  3.int pthread_attr_getschedparam(const pthread_attr_t *restrict attr,

  4. struct sched_param *restrict param);

  5.int pthread_attr_setschedparam(pthread_attr_t *restrict attr,

  6. const struct sched_param *restrict param);

  7. struct sched_param sched;

  8. sched.sched_priority = sched_get_priority_max(SCHED_FIFO);

  9. pthread_attr_setschedparam( attr, &sched );

  第二个方案的产生是在实现了第一个方案之后,发现多CPU或多core的情况下,仍然有漏报事件发生,漏报无规律可循,文件或目录的个数不定,.再做了多种模拟测试之后,发现在单CPU下,读事件是没有问题的,但是在多CPU下,读事件的线程是分配了core的个数个的.这时会发现读到的事件不是一般的乱,无规律可循.在没有任何分析的情况下,我假定inotify会对他内部的RB-Tree的读取做了同步的,为了效率就肆无忌惮的用多个线程去读了,结果在多U下,就给读乱了.在把读取线程改为一个后,就没有漏事件了;但是考虑到效率问题,还是要用多个线程去读的.或者可以对每个线程的read进行加锁,这样就可以保证读的时候,在iNotify的buffer里是同步的了.具体效果如何,还有待明天验证;

  在这里插一句,Windows的iocp是同步读的,是先read然后再getiocpstatus的,Linux的Epoll是反过来的,是异步读取的.个人觉得可能是ms已经对异步读的方式进行了测试,选定了同步读的方式,这样对写应用的人来说,是要省不少心的.还有一点,inotify没有加迭代监控子目录的参数,而Windows却有了这种考虑,这一点也算是win在设计上考虑比较全面的地方吧.

拥有帝国一切,皆有可能。欢迎访问phome.net

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号