【问题标题】:gevent using Queue get and socket recv at the same timegevent同时使用Queue get和socket recv
【发布时间】:2013-06-17 04:17:02
【问题描述】:

如标题所述

示例代码:

import gevent
from gevent.queue import Queue

class Worker(gevent.Greenlet):
    def __init__(self, sock):
        self.queue = Queue()
        self.sock = sock
        super(Worker, self).__init__()

    def _run(self):
        self.running = True
        while self.running:
            msg_from_queue = self.queue.get()    # block call
            msg_from_sock = self.sock.recv(128)  # block call

worker = Worker(sock)
worker.start()

我想让工人处理两个事件:

  1. 来自袜子的消息接收
  2. 从队列中获取消息

但是这两个都是块调用

我应该怎么做,让worker同时从sock和queue中获取?

【问题讨论】:

    标签: python gevent


    【解决方案1】:

    我找到了办法:

    class Worker(gevent.Greenlet):
        def _sock_recv(self):
            # ...
        def _queue_get(self):
            # ...
        def _run(self):
            recv = gevent.spawn(self._sock_recv)
            get = gevent.spawn(self._queue_get)
            gevent.joinall([recv, get])
    

    【讨论】:

      【解决方案2】:

      Worker 拆分成两个工人怎么样?

      class QueueWorker(gevent.Greenlet):
          def __init__(self, queue):
              self.queue = queue
              super(QueueWorker, self).__init__()
      
          def _run(self):
              self.running = True
              while self.running:
                  msg = self.queue.get()    # block call
                  print 'queue:', msg
      
      
      class SocketWorker(gevent.Greenlet):
          def __init__(self, sock):
              self.sock = sock
              super(SocketWorker, self).__init__()
      
          def _run(self):
              self.running = True
              while self.running:
                  msg = self.sock.recv(128)  # block call
                  print 'socket:', msg
      
      worker1 = QueueWorker(queue)
      worker1.start()
      worker2 = SocketWorker(sock)
      worker2.start()
      

      【讨论】:

      • 嗨,看下面,我找到了一种方法。但仍然感谢您的帮助
      • @Yueyoum, gevent.joinall() 等待所有作业完成。这就是你想要的吗?
      • 我不确定。 gevent.joinall() 只等待这个工人的子工作,而不是整个程序过程,对吧?在测试中,我创建了三/四个工人,现在工作正常。
      • gevnet.joinall([recv, get]) 等待recv, get both 完成,而不是整个程序过程。
      • 是的,这就是我想要的,joinall([recv, get]) 让两个greenlet 运行,recvget 之前完成。所以,我的项目中还有额外的代码:def clear(*args): get.kill(); recv.link(clear).So,当rece完成,然后杀死getgreenlate,最后,这个工人自动退出
      猜你喜欢
      • 1970-01-01
      • 2016-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-27
      • 2014-08-17
      • 2013-10-21
      • 2011-02-04
      相关资源
      最近更新 更多