2009-07-22 43 views
5

在我的应用程序中,我需要观察新文件的目录。流量非常大,每秒会出现至少数百个新文件。目前我使用一个繁忙的循环有这种想法:使用select/poll/kqueue/kevent观看新文件的目录

while True: 
    time.sleep(0.2) 
    if len(os.listdir('.')) > 0: 
    # do stuff 

运行分析,我看到了很多在睡眠中度过的时间后,我想知道我是否应该改变这种使用轮询代替。

我想用select中的一个可用类来轮询我的目录,但我不确定它是否真的有效,或者我只是做错了。

我得到一个FD我的目录中:

fd = os.open('.', os.O_DIRECT) 

然后我试过几种方法时,看到目录的变化。举个例子,我试过的一件事是:

poll = select.poll() 
poll.register(fd, select.POLLIN) 

poll.poll() # returns (fd, 1) meaning 'ready to read' 

os.read(fd, 4096) # prints largely gibberish but i can see that i'm pulling the files/folders contained in the directory at least 

poll.poll() # returns (fd, 1) again 

os.read(fd, 4096) # empty string - no more data 

为什么poll()的行为就像有更多的信息要读?我认为只有在目录中的内容发生变化时才会这样做。

我试图在这里甚至有可能做什么?

如果没有,是否有任何其他更好的替代while True: look for changes

回答

1

运行分析后,我看到很多时间花在睡眠,我想知道如果我应该改变它来使用轮询。

看起来你已经同步投票,通过定期检查状态。不用担心在sleep中花费的时间,它不会占用CPU时间。它只是将控制权交给操作系统,在请求的超时后唤醒进程。

你可以使用监听文件系统由操作系统提供更改通知图书馆考虑异步事件循环,但首先考虑是否让你在这种特殊情况下的任何真正的实惠。

3

为什么不使用Python包装来监视文件更改,比如gamin或inotify(搜索pyinotify,我只允许发布一个超链接作为新用户......) - 这是肯定的更快,低级的东西已经完成在C级为你,使用内核接口...

+0

我使用BSD所以inotify不可用,它看起来像gamin不是。 – gdm 2009-07-24 18:12:54

+0

gamin文档说它可以在FreeBSD上使用,但是使用的是不太理想的轮询解决方案 - 它可能仍然比其他任何东西都快,尽管 – 2009-07-25 08:16:47

6

FreeBSD和Mac OS X上的inotify提供所谓的kqueue的类似物。在FreeBSD机器上键入man 2 kqueue以获取更多信息。对于Freebsd上的kqueue,您可以在http://people.freebsd.org/~dwhite/PyKQueue/上获得PyKQueue,但不幸的是不会主动维护,因此您的里程可能会有所不同。

0

你可能想看看select.kqueue - 我没有用它,但kqueue的是这下BSD右侧接口相信这样就可以监视的文件/目录和被称为回来时,他们改变

当且仅
0

我已经写了一个库和一个shell工具来处理这个问题。

http://github.com/gorakhargosh/watchdog

虽然,kqueue的是监测目录 一个非常重量级的方式,我会很感激,如果你可以测试和检验过程中可能遇到的任何性能 问题。修补程序也是受欢迎的。

HTH。