V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
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 · 2020-11-17 17:00:45 +08:00 · 1602 次点击
    这是一个创建于 1499 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我这边遇到一个问题,使用 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 条回复    2020-11-18 09:50:59 +08:00
    cz5424
        1
    cz5424  
       2020-11-18 00:05:12 +08:00 via iPhone
    感觉是 Queue(),如果想要多线程多进程和协程,一般会避免全局变量
    catxo
        2
    catxo  
       2020-11-18 09:50:59 +08:00
    你的 worker 是一个循环,没有退出条件
    一般都是判断 item 为空作为退出条件
    ```python
    item = q.get()
    if not item:
    break
    do_work(wid, item)
    ```

    producer 里面,加上
    ```python
    for _ in range(4):
    q.put(None)
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2423 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 16:05 · PVG 00:05 · LAX 08:05 · JFK 11:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.