คิว gevent ล้มเหลวด้วย LoopExit

ฉันต้องการใช้ไลบรารี python gevent เพื่อใช้งานผู้ผลิตหนึ่งรายและเซิร์ฟเวอร์ผู้บริโภคหลายราย มีความพยายามของฉัน:

class EmailValidationServer():
   def __init__(self):
      self.queue = Queue()
   def worker(self):
      while True:
          json = self.queue.get()
   def handler(self,socket,address):
      fileobj = socket.makefile()
      content = fileobj.read(max_read)
      contents = json.loads(content)
      for content in contents:
          self.queue.put(content)
   def daemon(self,addr='127.0.0.1',num_thread=5):
      pool = Pool(1000)
      server = StreamServer((addr, 6000),self.handler,spawn=pool) # run
      pool = ThreadPool(num_thread)
      for _ in range(num_thread):
          pool.spawn(self.worker)
      server.serve_forever()
if __name__ == "__main__":
    email_server = EmailValidationServer()
    email_server.daemon()

ฉันใช้คิวจาก gevent.queue.Queue มันให้ข้อมูลข้อผิดพลาดแก่ฉัน:

LoopExit: This operation would block forever
(<ThreadPool at 0x7f08c80eef50 0/4/5>,
 <bound method EmailValidationServer.worker of <__main__.EmailValidationServer instance at 0x7f08c8dcd998>>) failed with LoopExit

ปัญหา: แต่เมื่อฉันเปลี่ยน Queue จากการใช้งานของ gevent ไปเป็นไลบรารี่ build-in ของ python มันก็ใช้งานได้ ฉันไม่ทราบเหตุผล ฉันคิดว่ามันได้รับการสนับสนุนให้มีความแตกต่างระหว่างการใช้งาน ฉันไม่ทราบสาเหตุที่ทำให้ gevent ไม่อนุญาตให้รออย่างไม่มีที่สิ้นสุด มีใครสามารถอธิบายได้บ้าง? ขอบคุณล่วงหน้า


person user3722836    schedule 16.04.2015    source แหล่งที่มา


คำตอบ (1)


ฉันขอแนะนำให้คุณสามารถใช้ gevent.queue.JoinableQueue() แทน Queue() ในตัวของ Python คุณสามารถดูคู่มือคิวอย่างเป็นทางการสำหรับการใช้งาน API (http://www.gevent.org/gevent.queue.html)

def worker():
    while True:
        item = q.get()
        try:
            do_work(item)
        finally:
            q.task_done()

q = JoinableQueue()
for i in range(num_worker_threads):
     gevent.spawn(worker)

for item in source():
    q.put(item)

q.join()  # block until all tasks are done

หากคุณพบข้อยกเว้นอีกครั้ง คุณควรทำความเข้าใจหลักการของโฟลว์การควบคุม Gevent corouinte อย่างถ่องแท้ ...เมื่อคุณเข้าใจประเด็นแล้ว นั่นก็ไม่ใช่เรื่องใหญ่อะไร :)

person Ryan Chou    schedule 08.12.2015
comment
@SuperBiasedMan ดีกว่าสำหรับการจัดรูปแบบบล็อคโค้ดของฉัน :) - person Ryan Chou; 08.12.2015