我正在使用Python Watchdog来监控Ubuntu上的文件夹.它可以正常使用1或2个文件,但是当我通过命令mv * .xml dest_folder移动50个文件时,它只收到2个事件并且只处理了2个文件.下面是代码.
def on_moved(self, event):
try:
logger.debug("on_moved event :" + str(event) )
self._validate_xml(event.dest_path)
except Exception as ex:
logger.exception(ex)
如果我注释掉_validate_xml函数,那么我会收到所有45个事件.
任何人都可以告诉我看门狗到底发生了什么,最好的解决办法是什么?
解决方法:
我没有使用Python Watchdog,但是从通用的实时系统角度来看,
>使用_validate_xml处理xml可能会很慢,并且会让您错过事件.
> event =类似于中断,处理应该尽可能快.
要在处理事件时执行的操作越多,系统的“实时”就越少.您可以做的是将xml有效性检查卸载到另一个进程,并使用Queue(消息将是event.dest_path)与您看到的路径交换消息.您的事件处理就像将消息放入队列一样简单,文件可以由队列的使用者批量处理.
简而言之:
>实例化一个队列
> fork()进程
>在on_moved处理程序中,将消息放入队列中,
>在分叉进程中,从队列中弹出消息并调用_validate_xml.
>您可以选择利用multiprocessing.Pool
并行验证xml文件.
祝好运.
编辑:在我的系统上测试;上面的大多数评论似乎都不适用,因为看门狗的代码似乎处理线程很好.
#!/usr/bin/env python
import time
from watchdog.observers import Observer, api
from watchdog.events import LoggingEventHandler, FileSystemEventHandler, FileMovedEvent
import logging
def counter_gen():
count = 0
while True:
count += 1
yield count
class XmlValidatorHandler(FileSystemEventHandler):
sleep_time = 0.1
COUNTER = counter_gen()
def on_moved(self, event):
if isinstance(event, FileMovedEvent):
print '%s - event %d; validate: %s' % (
type(self).__name__, self.COUNTER.next(), event.dest_path)
time.sleep(self.sleep_time)
class SlowXmlValidatorHandler(XmlValidatorHandler):
sleep_time = 2
COUNTER = counter_gen()
def get_observer(handler):
observer = Observer(timeout=0.5)
observer.event_queue.maxsize=10
observer.schedule(handler, path='.', recursive=True)
return observer
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
event_handler = LoggingEventHandler()
observer1 = get_observer(XmlValidatorHandler())
observer2 = get_observer(SlowXmlValidatorHandler())
observer1.start()
observer2.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer1.stop()
observer2.stop()
observer1.join()
observer2.join()
无法重现您的问题.一些指针:
>检查队列maxsize,如果你已经有物品并且没有得到及时处理,那么我的猜测是超时启动并且事件丢失.在这种情况下,您可能想要调整大小.
>检查超时,如果已配置,您可能需要调整该参数.
也许更完整的代码片段可以帮助我们.