2011-06-01 49 views
1

我正在使用twsited的INotify監視/ dev目錄以監視新添加的串行設備。我目前使用的代碼與下面類似。python twisted INotify without blocking reactor

notifier = INotify() 
notifier.watch(FilePath("/dev"), IN_CREATE, callbacks=[self.created]) 
notifier.startReading() 

def created(self, ignored, path, mask): 
    ... 
    blocking code 
    ... 

我目前遇到的問題是,當「創建」獲取調用,它擋住了我的反應器,以便其他網絡會話(我有TCP和用相同的反應器相關的UDP連接),必須等待爲'創建'方法完成。

有誰知道我如何使'創建'的方法在後臺運行,所以它不會阻止我的反應堆?

感謝,

西蒙

回答

7

在 「反應堆線」 扭曲運行所有的事件處理程序 - UDP, TCP,而且實際上是通知。他們都希望通過不阻塞來與系統合作。所以,從這個意義上講,這只是一個關於如何在Twisted中編寫好的事件處理程序的問題,而不是特別關於inotify。

有很多避免阻塞的選項。回答你的問題棘手的是,正確的選擇取決於爲什麼當前的代碼塊。

它是否執行套接字I/O?改爲使用Twisted'snon-blockingsocket I/O API。

它做文件系統I/O嗎?這裏您可能需要use a thread,因爲無阻塞的文件系統I/O很難(也許不是不可能)沒有一個。

它是否與SQL數據庫對話?也許twisted.enterprise.adbapi可以提供幫助。

依此類推。

我不知道這是否涵蓋你所處的情況。但是,我會強調兩件事。首先,在Twisted程序中使用線程是完全合理的。扭曲的存在很多,所以你不會使用線程,但如果你來到一個線程完成工作而沒有其他任何事情的情況 - 去爲它(謹慎;)。扭曲的甚至有一些幫手可以使它更容易,例如zeekay提到的deferToThread。其次,爲任務選擇合適的解決方案。所有「阻塞」問題的收集只比所有一般編程問題的收集略小。有很多可能的解決方案。有些與線程一樣,似乎具有廣泛的適用性,但有一點小心,您可能會發現更適合特定情況的東西。

此外,請看Twisted: Making code non-blocking作進一步解釋。

+0

感謝您的幫助和詳細的答案。我花了一些時間探索你提到的不同選項,而deferToThread選項似乎對我來說很好。不過你提到的一些看起來很有趣的事情是,你建議「使用Twisted的非阻塞套接字I/O API」。你能指出我在哪裏記錄這些嗎?再次感謝你的幫助。 – Simon 2011-06-15 10:01:07

+1

只是詳細的答案像我這樣一個新的扭曲的入門者需要。非常感謝! – egbutter 2011-12-18 22:18:41

+0

有關Twisted的非阻塞網絡I/O API的介紹,請參閱http://twistedmatrix.com/documents/current/core/howto/servers.html和http://twistedmatrix.com/documents/current/core/ HOWTO/clients.html – Glyph 2012-10-19 06:44:06

1

你可以使用twisted.internet.threads.deferToThread在一個線程中運行阻止代碼:

deferToThread(self.created, ignored, path mask)