推荐学习书目
› Learn Python the Hard Way
Python Sites
› PyPI - Python Package Index
› http://diveintopython.org/toc/index.html
› Pocoo
值得关注的项目
› PyPy
› Celery
› Jinja2
› Read the Docs
› gevent
› pyenv
› virtualenv
› Stackless Python
› Beautiful Soup
› 结巴中文分词
› Green Unicorn
› Sentry
› Shovel
› Pyflakes
› pytest
Python 编程
› pep8 Checker
Styles
› PEP 8
› Google Python Style Guide
› Code Style from The Hitchhiker's Guide
xiangyuhahah
V2EX  ›  Python

各位大佬,小弟使用 gevent 遇到了 loopexit 的错误

  •  
  •   xiangyuhahah · Nov 17, 2020 · 2540 views
    This topic created in 2138 days ago, the information mentioned may be changed or developed.

    我这边遇到一个问题,使用 gevent 的时候,报了 loopexit 的错误。

    import random
    from Queue import Empty
    import gevent
    from gevent.queue import *
    
    import gevent.monkey
    gevent.monkey.patch_all()
    
    
    q = Queue()
    workers = []
    
    
    def do_work(wid, value):
        gevent.sleep(random.randint(0,2))
        print 'Task', value, 'done', wid
        return
    
    
    def worker(wid):
        while True:
            try:
                item = q.get()
                if item:
                    do_work(wid, item)
            except StopIteration:
                break
            except Empty:
                break
    
    
    def producer():
        for i in range(4):
            workers.append(gevent.spawn(worker, random.randint(1, 888888)))
    
        for item in range(1, 9):
            q.put(item)
    
    
    producer()
    gevent.joinall(workers)
    

    我查了网上的资料,看了 gevent 的原理,但是没怎么看明白。网上主流的解释是任务流已经消费完了,协程都在做 waiter 的操作,导致 gevent 的 joinall 失败了。我没有理解这个过程。现在的我的解决办法是,消费完任务之后协程会报空的错误,捕捉一下就退出协程。但是我感觉这样只是掩盖了问题,没有解决问题。

    item = q.get() >>item = q.get(block=False)
    

    各位大佬怎么理解 loopexit ?

    2 replies  •  2020-11-18 09:50:59 +08:00
    cz5424
        1
    cz5424  
       Nov 18, 2020 via iPhone
    感觉是 Queue(),如果想要多线程多进程和协程,一般会避免全局变量
    catxo
        2
    catxo  
       Nov 18, 2020
    你的 worker 是一个循环,没有退出条件
    一般都是判断 item 为空作为退出条件
    ```python
    item = q.get()
    if not item:
    break
    do_work(wid, item)
    ```

    producer 里面,加上
    ```python
    for _ in range(4):
    q.put(None)
    ```
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2589 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 01:22 · PVG 09:22 · LAX 18:22 · JFK 21:22
    ♥ Do have faith in what you're doing.