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

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 ?

有帮助吗?

解决方案

运行分析后,我发现很多时间都花在睡眠上,我想知道是否应该更改它以使用轮询。

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

您可以考虑使用一个库来监听操作系统提供的文件系统更改通知的异步事件循环,但首先考虑它在这种特定情况下是否能给您带来任何真正的好处。

其他提示

FreeBSD 和 Mac OS X 提供了一个类似于 inotify 的工具,称为 kqueue。在 FreeBSD 机器上输入 man 2 kqueue 以获取更多信息。对于 Freebsd 上的 kqueue,您可以在以下位置找到 PyKQueue: http://people.freebsd.org/~dwhite/PyKQueue/, ,遗憾的是没有积极维护,因此您的里程可能会有所不同。

为什么不使用 Python 包装器来监视文件更改的库之一,例如 加明 或 inotify (搜索 pyinotify,我只允许作为新用户发布一个超链接...) - 这肯定会更快,并且低级内容已经在 C 级别为您完成,使用内核接口。 。

您可能想看看 选择.kqueue - 我没有使用过它,但 kqueue 是 BSD 下的正确接口,我相信这样你就可以监视文件/目录,并在且仅当它们更改时被回调

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

http://github.com/gorakhargosh/watchdog

虽然,Kqueue是监视目录的一种非常重量的方式,如果您可以测试并结帐可能遇到的任何性能问题,我会感谢。也欢迎补丁。

HTH。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top