2009-07-22 77 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。