2013-10-02 43 views
1

我想:呼叫並等待(一會兒)的異步事件在Python

  1. 啓動異步任務(類似Django的芹菜或GEVENT)
  2. 等待有限的時間量任務完成(1秒),
  3. 然後繼續不殺任務。

我注意到這個相關線程https://stackoverflow.com/a/13001153/226800;然而,在接受的答案中,當'g'被破壞時,任務是否也會被破壞?即使在任務的創建者已經返回後,我仍然希望允許任務在後臺運行,等待一段時間後。

+0

我看不到我的答案中缺少的東西;我可以保證事實上是正確的 - 但你不相信我? –

+0

我認爲它需要清理成爲一個「正確的」答案。您粘貼的代碼實際上比您的答案更正確。在任務超時之後,我無法獲得任何東西(即使在添加一段時間的睡眠之後),但在您的示例中仍然繼續執行任務。 – brianray

+0

另外,我想澄清一個問題,我真的想完全從調用者返回,如果在Django的請求/響應循環中使用類似Gevent的事件,這些事件會發生什麼?他們以某種方式在全球註冊?我真的認爲http://stackoverflow.com/questions/9034091/how-to-check-task-status-in-celery可能是我的答案。你同意嗎? – brianray

回答

1

編輯:是的,如果你調用g.kill(),任務「載」由g也儘快殺死(即在第一個合作上下文切換)......,嗯,那是種了點,如果你想一想。

在GEVENT,這是你會怎麼做:

import gevent 

def task(): 
    for _ in range(10): 
     print "processing" 
     gevent.sleep(1.0) 
    return 'result' 

task_g = gevent.spawn(task) 
res = task_g.join(timeout=3.0) 
if res is None: 
    print "task timed out but is continuing" 
else: 
    print "got result: ", res 

如果你而喜歡一個異常基於流的,你可以使用with_timeout;這也有個好處,你可以從你的任務返回None,並沒有它混淆超時:

import gevent 
from gevent.timeout import Timeout, with_timeout 

def task(): 
    ... 

task_g = gevent.spawn(task) 

try: 
    result = with_timeout(3.0, task_g.join) 
except Timeout: 
    print "timeout" 
    result = None 
else: 
    print "got result:", result 

以後你仍然可以殺死的任務,如果出由task_g.kill()它「完全」時代。

+0

我認爲當我的程序完成我的greenlet(由gevents包裹)的生命週期時,無論結果如何都會被終止。不知道這是如何在運行Django進程的上下文中工作的。你知道嗎? – brianray

+0

使用'subprocess'?我認爲如果父進程死亡,它應該會被殺死。 –

+0

@brianray:我可以以某種方式改進/修改我的答案,使其可以接受嗎? –