2012-05-15 43 views
2

它在下面產生一個新的線程嗎?如果傳統的Web服務器產生一個線程來提供一個HTTP請求和Twisted web,那麼每次我想查詢mysql時都必須生成一個Deferred() - 增益在哪裏?看起來它不會產生敏感,如果它產生了一個線程,那麼它是如何實現的?扭曲的延遲是如何實現的?

+3

你看過源代碼嗎? – XORcist

+2

如果你真正想要了解AIO,那是一個更大的問題,而不是真正關於延遲(或扭曲,甚至是Python)的問題。雖然有更新的方法,但您可以先閱讀關於「select()」調用和「O_NONBLOCK」標誌。 –

回答

2

Python中的Deferred沒有做任何事情,它與線程或進程或其他任何東西都沒有關係。

這是一個承諾的抽象,用於將來要傳遞的數據以及該數據如何映射到接收回調函數。

This is documented very well.

如何扭曲達到異步行爲被記錄在案很好在被扭曲的文檔和新聞組檔案,簡單的谷歌搜索會找到你所需要的。它與推遲的實施無關。如果您仍然不明白,您需要在另一個問題中詢問具體信息,而不是在對此答案的評論中。

也就是說,Twisted在併發性方面是死的,它永遠不會擴展到多核處理器以及像Erlang這樣的東西,這是我在Twisted退出擴展時從Twisted轉移到的東西。

+0

對不起,我的問題不準確。我的意思是:如何實現無阻塞的東西 - 例如 - 我使用twisted.enterprise.adbapi或其他接口訪問其他數據庫(cassandra,memcache等)來查詢MySQL。代碼執行沒有被阻止,並且它同時連接到數據庫並運行查詢。所以我想知道下面的實現是否創建了一個新線程? – PawelRoman

+0

@JarrodRoberson對於這個問題,這並不是真正的主題,但你對扭曲縮放並不是很正確。在PyPy正在進行的STM的實施中,應該可以製作一個STM啓用的反應器,它將實際上並行處理多個回調鏈。 –

+0

我們正在運行CPython,這是7年前。誰會在企業生產系統中運行PyPy,每天負責數億次交易?或現在?根據他們自己的事務內存捐贈頁面上的文檔,PyPY仍然有一個GIL。 *「GIL或全局解釋器鎖是CPython和(迄今爲止)PyPy中的一個單一鎖,所有線程都必須獲取才能執行Python字節碼。這意味着迄今爲止,在Python中,即使使用線程,我們在多核性能方面不會獲得任何好處。「*所以我現在是正確的。 –

3

正如其他人所說的那樣,Deferred本身就是一種價值的承諾,也是價值到達時的一系列事情(或者當獲得價值失敗時)。

它們的工作原理是這樣的:有些函數看到它想返回的值還沒有準備好。因此,它準備一個延期,然後以某種方式安排該延期爲回調(「已解僱」)與值一旦準備就緒。第二部分是可能導致你混淆的部分;延遲自己不控制何時或如何被解僱。這是延期創建的任何責任。

在整個Twisted應用程序的環境中,幾乎所有事件都是基於事件的,事件由反應器管理。假設你的代碼使用twisted.web.client.getPage(),所以它現在有一個Deferred,它會被http提取的結果觸發。這意味着getPage()啓動了與http服務器的tcp會話,並且在反應堆中基本安裝了處理程序,說「如果在此tcp連接上看到任何流量,請調用此協議對象的方法」。一旦協議對象看到它已經收到了你要求的整個頁面,它會觸發你的延期,因此你自己的代碼通過該延遲的回調鏈被調用。

所以一切都是回調和掛鉤,一路下降。這就是爲什麼你不應該在Twisted應用程序中阻塞代碼,除非在一個單獨的線程上 - 因爲它會阻止一切被處理。

這有幫助嗎?