python-3.x - Flask 中的线程不能与 UWSGI 一起使用,但可以在命令行上工作

标签 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()

我希望调用/路由会打印“Interrupted by request!”在控制台上,但它只是挂起,即使作业应该在单独的线程中运行。

我的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 交互有关,但这是一个疯狂的猜测,我不知道如何阻止它。

最佳答案

对我来说,使用 uwsgi 标志 --lazy 有效。

uwsgi foo.ini --socket=0.0.0.0:5000 --protocol=http --lazy -w wsgi

说明:

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

single process (no master):

the process creates the thread in which the WSGI callable put data.

This is ok

with master process:

the master load the app and generate the thread. Then it forks one or more workers. This workers are new processes with no relation with the thread spawned in the master. So your data will go nowhere (only the master can access the initial thread).

You have two way to follow:

1) add --lazy to the command line, in this way your app will be loaded after master's fork, so each worker will get its thread.

2) rewrite your app to use the uwsgi.post_fork_hook feature.

关于python-3.x - Flask 中的线程不能与 UWSGI 一起使用,但可以在命令行上工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51931262/

相关文章:

python - nginx + uwsgi + flask - 禁用自定义错误页面

python - 如何让pandas.Series.str.get_dummies() 报NaN?

python - 循环遍历 JSON 文件的文件夹以从 Python 中的每个文件中提取相同的关键字

python - 在 jinja2 模板中创建指向 Flask 应用程序 url 的链接

python - 如何在 python Flask 中安排定时事件?

python - 如何在 django、uwsgi 和 nginx 设置中反射(reflect) python 的变化

python - 导入错误 : No module named psycopg2 after install

python-3.x - Python : Running nested loop, 2D 移动窗口,并行

python-3.x - 当参数可以具有从特定基类型派生的任何类型时,如何注释抽象方法的参数类型?

python - 如何使用 Flask 返回相对 URI Location header ?