2011-12-08 41 views
0

我的項目需要多個線程從同一個文件夾讀取文件。該文件夾包含傳入文件,該文件只能由其中任何一個線程處理。後來,這個文件讀取線程,處理它後刪除文件。從Linux上的單個文件夾讀取多個線程

第一次回答後編輯:我不希望單個線程負責讀取文件名並將這些名稱提供給其他線程,以便他們可以讀取它。

是否有任何有效的方式來實現這個python?

+5

爲什麼你不想使用單個線程將輸入文件名傳遞給其他線程? – jfs

+0

如果我這樣做,這個輸入閱讀線程需要充當一個調度程序,它將文件名提供給空閒線程。相反,如果有什麼東西可以幫助我實現這一點,那將是非常棒的。 – Sujit

+0

@Sujit你不會找到不依賴於工作隊列模型的東西。你爲什麼不想用它?我可以向你保證,它不會是瓶頸 - 磁盤訪問將是。 –

回答

2

您應該使用Queue module。從文檔:

隊列模塊實現多生產者,多消費者隊列。當信息必須在多個線程之間安全地交換時,它在線程編程中特別有用。

我會使用FIFO方法,負責檢查入站文件並對它們進行排隊,還有一些工作人員正在處理它們。該模塊還支持LIFO方法或使用自定義方法分配優先級的方法。


編輯:如果你不想使用Queue模塊,你是下* nix的系統,你可以使用fcntl.lockf代替。另一種方法是用os.open('filename', os.O_EXLOCK)打開文件。

根據您執行此操作的頻率,您可能會發現它的性能低於使用Queue,因爲您必須考慮競爭條件(即:您可能獲取要打開的文件的名稱,但文件可能會在你有機會打開它之前被另一個線程鎖定,拋出一個你必須捕獲的異常)。 Queue是有原因的! ;)


EDIT2:評論在這個問題和其他問題都帶來了問題,同時磁盤訪問不同的文件和隨之而來的性能損失。我在想task_done會被用來防止這種情況發生,但是讀到其他人的意見,我發現不是排隊文件名,而是直接排隊文件的內容。這第二個替代方案僅適用於有限數量的有限大小的排隊文件,因爲否則RAM會相當快地填滿。

我不知道RAID和其他並行磁盤配置是否已經照顧每個磁盤讀取一個文件,而不是在兩個磁盤上的兩個文件之間來回彈跳。

HTH!

+0

這裏的問題是,如何從同一個文件夾讀取並確保兩個線程不讀取同一個文件? – Sujit

+2

@Sujit - ...答案恰恰就是這個。什麼部分不清楚? – mac

+0

我不想讓一個線程負責讀取文件名並將文件名提供給其他線程。把它看作是對文件夾或其他東西的鎖定。你知道我的意思?在你的方法中,你有一個負責入站文件的線程。我不想那樣。 – Sujit

1

如果你想讓多個線程直接從同一個文件夾中並行讀取幾個文件,那麼我必須讓你失望。從單個磁盤並行讀取並不是一個可行的選擇。單個磁盤需要旋轉並尋找下一個要讀取的位置。如果您正在閱讀多個線程,則只是在搜索之間彈跳磁盤,性能比簡單的順序讀取要差得多。

只要堅持mac的建議,並使用單線程閱讀。

+0

@ mac的建議中的隊列包含文件名,因此多個線程可能會從不同的文件同時讀取。目前還不清楚它是否比在一個線程中讀取所有文件慢。 – jfs

+0

@ J.F.Sebastian - 查看我的第二個編輯! :) – mac

+0

@mac:還有文件緩存,Python中管道數據的開銷等等。我會選擇線程之間的低耦合,除非分析器另有說明。 – jfs