使用select/poll/kqueue/kevent来查看新文件的目录

gdm*_*gdm 5 python asynchronous freebsd polling

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

while True:
  time.sleep(0.2)
  if len(os.listdir('.')) > 0:
    # do stuff
Run Code Online (Sandbox Code Playgroud)

运行性能分析后,我看到很多时间都在睡眠中,我想知道是否应该改变它来使用轮询.

我正在尝试使用其中一个可用的类select来轮询我的目录,但我不确定它是否真的有效,或者我是否只是做错了.

我为我的目录获得了一个fd:

fd = os.open('.', os.O_DIRECT)
Run Code Online (Sandbox Code Playgroud)

然后我尝试了几种方法来查看目录何时更改.举个例子,我尝试过的一件事是:

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
Run Code Online (Sandbox Code Playgroud)

为什么poll()表现得有更多的信息需要阅读?我假设只有在目录中发生了某些变化时才会这样做.

我想在这里做什么甚至可能吗?

如果没有,还有其他更好的选择while True: look for changes吗?

Kur*_*urt 6

FreeBSD和Mac OS X提供了一个名为kqueue的inotify模拟.在FreeBSD机器上键入man 2 kqueue以获取更多信息.对于Freebsd上的kqueue,您可以在http://people.freebsd.org/~dwhite/PyKQueue/上找到PyKQueue ,但遗憾的是没有积极维护,所以您的里程可能会有所不同.


Ada*_*tek 1

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

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

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