V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
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 · 2216 views
    This topic created in 1999 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   ·   Solana   ·   4566 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 44ms · UTC 10:06 · PVG 18:06 · LAX 03:06 · JFK 06:06
    ♥ Do have faith in what you're doing.