使用gevent.queue.queue.get():gevent.hub.LoopExit:'这次行动将永远封锁'

2024-04-24 14:35:11 发布

您现在位置:Python中文网/ 问答频道 /正文

在过去的几天里,我一直在尝试将事件流集成到我的flask应用程序中,在我的本地测试中取得了不错的结果,但是在服务器上使用uWSGI运行应用程序时,情况会更糟。我的代码基本上是建立在来自flask的example之上的。我正在使用python 3.4.2。在

问题

在我的uWSGI服务器上运行应用程序时,每当客户机尝试连接到/streaming端点时,它就会引发gevent.hub.LoopExit: 'This operation would block forever'.。我的假设是,这是由于无限期地调用空队列上的get()引起的。在

完全回溯:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/werkzeug/wsgi.py", line 691, in __next__
    return self._next()
  File "/usr/lib/python3/dist-packages/werkzeug/wrappers.py", line 81, in _iter_encoded
    for item in iterable:
  File "./voting/__init__.py", line 49, in gen
    result = queue.get(block=True)
  File "/usr/local/lib/python3.4/dist-packages/gevent/queue.py", line 284, in get
    return self.__get_or_peek(self._get, block, timeout)
  File "/usr/local/lib/python3.4/dist-packages/gevent/queue.py", line 261, in __get_or_peek
    result = waiter.get()
  File "/usr/local/lib/python3.4/dist-packages/gevent/hub.py", line 878, in get
    return self.hub.switch()
  File "/usr/local/lib/python3.4/dist-packages/gevent/hub.py", line 609, in switch
    return greenlet.switch(self)
gevent.hub.LoopExit: ('This operation would block forever', <Hub at 0x7f717f40f5a0 epoll default pending=0 ref=0 fileno=6>)

我的代码

/streaming端点:

^{pr2}$

向队列添加事件:

def notify():
    msg = {"type": "users", "data": db_get_all_registered(session_id)}
    subscriptions.add_item(session_id, msg)      # Adds the item to the relevant queues.

gevent.spawn(notify)

如前所述,它使用werkzeug在本地运行良好:

from app import app
from gevent.wsgi import WSGIServer
from werkzeug.debug import DebuggedApplication

a = DebuggedApplication(app, evalex=True)
server = WSGIServer(("", 5000), a)
server.serve_forever()

我试过了什么

  • 猴子用monkey.patch_all()修补。

  • Queue切换到{}。

  • gevent.sleep(0)Queue.get()结合使用。


Tags: inpyselfgetreturnlibpackagesusr
1条回答
网友
1楼 · 发布于 2024-04-24 14:35:11

这个异常基本上意味着在这个循环/线程中没有其他greenlet可以切换到。所以当绿叶被挡住的时候(队列.get()),中心无处可去,无事可做。在

同样的代码也可以在gevent的WSGIServer中工作,因为服务器本身是一个运行插座.接受循环,所以总有另一个绿色小菜可以换。但是很明显uwsgi不是这样工作的。在

解决这个问题的方法是安排其他的绿色小菜运行。例如,与其生成一个greenlet以按需通知,不如安排这样一个greenlet已经在运行并阻塞它自己的队列。在

相关问题 更多 >