2013-10-02 46 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:我可以以某种方式改进/修改我的答案,使其可以接受吗? –