【问题标题】:Wait until one of several greenlets finished等到几个greenlets之一完成
【发布时间】:2012-11-27 07:03:51
【问题描述】:

我有两个函数从两个不同的连接接收数据,我应该在从其中一个连接获得结果后关闭这两个连接。

def first():
    gevent.sleep(randint(1, 100))  # i don't know how much time it will work
    return 'foo'

def second():
    gevent.sleep(randint(1, 100))  # i don't know how much time it will work
    return 'bar'

然后我生成每个函数:

lst = [gevent.spawn(first), gevent.spawn(second)]

gevent.joinall 阻塞当前的 greenlet,直到来自 lst 的两个 greenlet 都准备好。

gevent.joinall(lst)  # wait much time
print lst[0].get(block=False)   # -> 'foo'
print lst[1].get(block=False)   # -> 'bar'

我想等到第一个或第二个 greenlet 准备好:

i_want_such_function(lst)  # returns after few seconds
print lst[0].get(block=False)  # -> 'foo' because this greenlet is ready
print lst[1].get(block=False)  # -> raised Timeout because this greenlet is not ready

我该怎么做?

【问题讨论】:

    标签: python gevent greenlets


    【解决方案1】:

    您可以使用 gevent.event.Event(或 AsyncResult)和 Greenlet 的 link() 方法,如下所示:

    ...
    ready = gevent.event.Event()
    ready.clear()
    
    def callback():
        ready.set()
    
    lst = [gevent.spawn(first), gevent.spawn(second)]
    for g in lst:
        g.link(callback)
    
    ready.wait()
    ...
    

    【讨论】:

      【解决方案2】:

      callback 接收 gevent 子进程,你可以得到例如从中返回值

      ...
      
      cars = []
      
      def _callback(job):
          cars.append(job.value)
      
      for car in xml_all_cars:
          print "creating jobs"
          g_parse = Greenlet.spawn(myMainFunction)
          g_parse.start()
          g_parse.link(_callback)
          jobs.append(g_parse)
      
      print "starting all jobs"
      gevent.joinall(jobs)
      print "jobs done"
      
      return cars
      

      cars 将包含 myMainFunction 返回的所有值的列表(对于每辆汽车)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-09
        • 1970-01-01
        • 1970-01-01
        • 2017-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多