Flask中的线程不适用于UWSGI,但可以在命令行中使用

时间:2018-08-20 12:56:09

标签: python-3.x flask uwsgi python-multithreading gil

我有一个Flask应用程序,该应用程序在命令行上运行时运行良好,但是当通过uWSGI运行时,它无法正确响应请求,或者工作线程无法正常运行。我已经重写了一个简单的概念验证/失败程序来演示该问题:

from datetime import datetime
from threading import Event, Thread

from flask import Flask


class JobManager:
    def __init__(self):
        self.running = False
        self.event = Event()

    def start(self):
        self.running = True
        while self.running:
            print("Processing Job at", datetime.now().strftime('%c'))
            self.event.clear()
            self.event.wait(5)
            if self.event.is_set():
                print("Interrupted by request!")

    def stop(self):
        self.running = False
        self.event.set()


app = Flask(__name__)
jobs = JobManager()

t = Thread(target=jobs.start)
t.start()

@app.route('/')
def hello_world():
    global jobs
    jobs.event.set()

    return "I'm alive at " + datetime.now().strftime('%c')


if __name__ == '__main__':
    app.run()

我希望调用/路由将显示“被请求中断!”在控制台上,但是即使作业应该在单独的线程中运行,它也只是挂起。

我的uWSGI配置为:

[uwsgi]
module = app:app

master = true
processes = 5
threads = 2

socket = 0.0.0.0:5000
protocol = http

reload-mercy = 5
worker-reload-mercy = 5

die-on-term = true
enable-threads = true
thunder-lock = true

logto = /home/user/dev/flask-thread/uwsgi_log.log
logto2 = /home/user/dev/flask-thread/uwsgi2_log.log

env = PATH=/home/user/dev/flask-thread/env/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

然后我用以下命令在venv中运行uWSGI:uwsgi --ini uwsgi-test.ini

如果我使用python app.py并使用内置的flask开发服务器,它将可以正常工作。

我唯一的猜测是,它与GIL与uWSGI的交互有关,但这是一个疯狂的猜测,我不知道如何阻止它。

1 个答案:

答案 0 :(得分:4)

对我来说,使用uwsgi标志const WebSocket = require('ws'); const ws = new WebSocket('wss://1'); const w = new WebSocket('wss://2') let myval1; let myval2; function compareValues(a, b) { // Do some kind of comparison here. if (a === b) { // Do a thing. }; } ws.on('message', function incoming(data) { myval1= JSON.parse(data); compareValues(myval1, myval2); }); w.on('message', function incoming(data) { myval2= JSON.parse(data); compareValues(myval1, myval2); }); 有用。

--lazy

说明:

引用http://lists.unbit.it/pipermail/uwsgi/2011-June/002307.html

  

单个进程(无主进程):

     

该过程创建WSGI可调用放置数据的线程。

     

没关系

     

具有主过程:

     

主服务器加载应用程序并生成线程。然后叉一个或   更多的工人。这些工人是新的过程,与   主线程中产生的线程。因此,您的数据将无处可去(只有   管理员可以访问初始线程。

     

您有两种方法可以跟踪:

     

1)在命令行中添加--lazy,这样您的应用将被加载   在师父拨叉之后,每个工人都将得到其线程。

     

2)重写您的应用程序以使用uwsgi.post_fork_hook功能。