【问题标题】:Exception gevent.hub.LoopExit: LoopExit('This operation would block forever',)Exception gevent.hub.LoopExit: LoopExit('此操作将永远阻塞',)
【发布时间】:2015-06-01 22:20:24
【问题描述】:

当我使用 Websockets 运行我的 Flask 应用程序时,我总是遇到这个错误。 我已尝试遵循本指南 - http://blog.miguelgrinberg.com/post/easy-websockets-with-flask-and-gevent

我有一个烧瓶应用程序,它为我的网络嗅探器提供 GUI 界面。嗅探器位于线程内部,如下所示:(l 是我的嗅探器的线程;isRunning 是一个布尔值,用于检查线程是否已经在运行)

try:
    if l.isRunning == False:  # if the thread has been shut down
        l.isRunning = True  # change it to true, so it could loop again
        running = True
        l.start()  # starts the forever loop / declared from the top to be a global variable
        print str(running)
    else:
        running = True
        print str(running)
        l.start()
except Exception, e:
    raise e
return flask.render_template('test.html', running=running)  #goes to the test.html page

嗅探器在没有 socketio 的情况下运行良好,我可以在遍历我的 gui 时嗅探网络。但是,当我在代码中包含 socketio 时,我首先在我的索引页面中看到 socketio 工作并且我能够接收从服务器到页面的消息。我也可以很好地遍历我的 GUI 中的其他静态页面;但是,激活我的线程网络嗅探器会使我的浏览器挂断。我总是收到 Exception gevent.hub.LoopExit: LoopExit('This operation will block forever',) 错误,当我重新运行我的程序时,控制台会说该地址已被使用。在我看来,发生这种情况时我可能没有正确关闭我的套接字。我也认为某些操作是基于错误阻塞的。我的python烧瓶应用程序中的代码如下所示

def background_thread():
    """Example of how to send server generated events to clients."""
    count = 0
    while True:
        time.sleep(10)
        count += 1
        socketio.emit('my response',{'data': 'Server generated event', 'count': count},namespace='/test')
if socketflag is None:
    thread = Thread(target=background_thread)
    thread.start()


@socketio.on('my event', namespace='/test')
def test_message(message):
    emit('my response', {'data': message['data']})

@socketio.on('my broadcast event', namespace='/test')
def test_message(message):
    emit('my response', {'data': message['data']}, broadcast=True)

@socketio.on('connect', namespace='/test')
def test_connect():
    emit('my response', {'data': 'Connected'})

@socketio.on('disconnect', namespace='/test')
def test_disconnect():
    print('Client disconnected')

这是我的索引页中的代码。

<script type="text/javascript" charset="utf-8">
        $(document).ready(function() {
            namespace = '/test'; // change to an empty string to use the global namespace

            // the socket.io documentation recommends sending an explicit package upon connection
            // this is specially important when using the global namespace
            var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);
            socket.on('connect', function () {
                socket.emit('my event', {data: 'I\'m connected!'});
            });

            // event handler for server sent data
            // the data is displayed in the "Received" section of the page
            socket.on('my response', function (msg) {
                $('#log').append('<br>Received #' + msg.count + ': ' + msg.data);
            });
        });
  </script>

【问题讨论】:

  • 您能否将错误的完整堆栈跟踪添加到您的问题中?另外,你是不是在给Thread打补丁?

标签: python multithreading flask socket.io flask-socketio


【解决方案1】:

我不久前遇到了这个问题,这是由于没有正确修补 threading 模块造成的。

在您的应用顶部,应用 gevent 补丁:

from gevent import monkey, sleep
monkey.patch_all()

【讨论】:

    【解决方案2】:

    您应该避免将 time.sleep() 与 gevent 一起使用。 您应该改用gevent.sleep()time.sleep() 会阻塞 gevent 循环

    【讨论】:

      【解决方案3】:

      来自https://github.com/gevent/gevent/issues/585#issuecomment-122406552

      确保您的 GEvent Pool 大小大于 1。如果设置为 1,则 GEvent 在处理事件时将没有任何工作人员可以切换,因此会报错。

      【讨论】:

        猜你喜欢
        • 2015-12-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多