2014-06-19 26 views
0

首先,我知道我可以使用線程來完成這樣的任務,像這樣:執行Python代碼的任務蕾

import Queue 
import threading 


# called by each thread 
def do_stuff(q, arg): 
    result = heavy_operation(arg) 
    q.put(result) 

operations = range(1, 10) 

q = Queue.Queue() 

for op in operations: 
    t = threading.Thread(target=do_stuff, args = (q,op)) 
    t.daemon = True 
    t.start() 

s = q.get() 
print s 

然而,在谷歌應用程序引擎有一些所謂的NDB微進程,並根據他們的您可以使用它們並行執行代碼。

Tasklet是一種編寫併發運行函數的方法,不需要 線程; tasklet通過事件循環執行,並可以使用yield 語句暫停自己阻止I/O或某些其他操作。阻塞操作的概念被抽象爲Future類,但是一個tasklet也可能產生一個RPC,以等待 RPC完成。

是否有可能完成類似上面的線程示例?

我已經知道如何使用get_async()處理檢索實體(從文檔頁面的示例中獲得它),但在並行代碼執行方面對我來說很不清楚。

謝謝。

+0

注意,線程是唯一真正的平行,如果他們釋放GIL,所以它有一個編譯擴展與nogil被調用,I/O等 – Davidmh

+0

我看到這個演示HTTP://www.dabeaz。 com/python/GIL.pdf,它明確說明你用它得到了什麼,但是在我的情況下,我可以獲得更好的性能......但它仍然不能回答我的問題。 – vertazzar

+0

如果您嘗試在面對請求的前面使用線程,則它們的運行時間不能超過請求生存時間。另外,如果你沒有使用任何谷歌服務(rpc),你將不會得到任何真正的併發性,因爲你有一個核心。我過去的測試顯示沒有irpc的前端線程會讓速度變慢。 –

回答

0

答案取決於你的heavy_operation究竟是什麼。如果heavy_operation使用RPC(遠程過程調用,例如數據存儲訪問,UrlFetch等...),那麼答案是肯定的。

how to understand appengine ndb.tasklet? 我問了一個類似的問題,你可能會在那裏找到更多的細節。

我可以把任何類型的代碼放在一個函數中,並將它裝飾爲ndb.tasklet嗎?之後將其用作異步函數。或者它必須是appengine RPC?

答案

技術上是可以的,但它不會異步運行。當您使用@tasklet裝飾非屈服函數時,它的Future值將在您調用該函數時進行計算和設置。也就是說,當你調用它時,它會貫穿整個函數。如果你想實現異步操作,你必須屈從於異步工作。通常在GAE中,它將一直工作到RPC調用。

+0

前段時間我讀過這個話題,並不明白它是否會異步執行它們。至於我的代碼,不,它不會執行任何RPC調用,所以我猜它不能異步工作 – vertazzar