【问题标题】:python flask threaded true not workingpython烧瓶线程真的不工作
【发布时间】:2017-10-18 15:19:46
【问题描述】:

threaded=True 的每个请求都在一个新线程中处理。但是,如果我将 threading true 设置为我的应用程序,它会显示未知行为。

这是我的代码。

from flask import Flask
from flask import jsonify
import time

app = Flask("proxapp")

import datetime

@app.route('/slow')
def slow():
    start = datetime.datetime.now()
    time.sleep(10)
    return jsonify(start = start, end = datetime.datetime.now())


try:
    app.run(threaded=True)
except Exception, e:
    print repr(e)

我在 Windows 中打开了两个选项卡,并尝试在不同的选项卡中请求相同的 url。只有在第一个请求被提供后,第二个请求才会被提供。第二个请求大约需要 20 秒才能得到处理。

我的代码有什么问题?

【问题讨论】:

  • 我不知道 Flask 使用的是哪种线程,但 Python 一次只能运行 一个 本机 Python 线程。
  • 因为默认的烧瓶 WSGI 无论如何都只用于开发,我建议从一开始就切换到 Gevent 或 gunicorn,也可以解决问题flask.pocoo.org/docs/0.12/deploying/wsgi-standalone/…
  • 2020 年进来的人可能会注意到这个 sn-p 完美运行,线程化,10 秒内 2 个线程。只需更新旧的 py2 打印和除声明。

标签: python multithreading flask


【解决方案1】:

来自关于部署选项的烧瓶文档

虽然轻量级且易于使用,但 Flask 的内置服务器不适合生产,因为它不能很好地扩展,并且默认情况下一次只处理一个请求。此处记录了一些可用于在生产环境中正确运行 Flask 的选项。

这就是为什么在第一个请求完成之前不会发生第二个请求的原因,因为烧瓶服务器本身一次只能处理一个请求。要解决这个问题,您需要在某种部署服务器上运行 Flask,例如 gunicornuWSGI,这似乎是最流行的。

您还可能会发现thisthis 问题的答案很有帮助。 Deployment Options 也有很多关于解决问题的不同方法的指南和信息的链接。

【讨论】:

  • 你引用的文字说:“默认情况下一次只处理一个请求”。 OP 通过指定 threaded=True 覆盖默认行为。
【解决方案2】:

我似乎找不到我的参考资料,但我记得从另一篇 SO 帖子中读到为什么尽管线程 = True,但在请求形成同一路由时来自同一浏览器的两个选项卡会失败。

这篇文章的要点是,虽然线程可以更好地处理同一个应用程序的多个连接,但浏览器本身会尝试重用任何已经打开的连接。因此,通过您的两个选项卡设置,您可以从不同的路由请求并且它工作正常,但是如果您从同一路由请求,由于浏览器回收连接,您会遇到问题。尝试打开两个不同的浏览器并进行测试。我再次为没有原始参考资料而道歉,我想感谢作者。如果我找到它我会更新这篇文章。

【讨论】:

    【解决方案3】:

    Python 的 GIL 一次只允许运行 1 个线程。所以 2 个请求总共需要 20 秒。它们是一次运行一个还是相互交错取决于很多因素,包括操作系统。

    【讨论】:

      【解决方案4】:

      我发现了最棘手的问题! 无论您使用的是什么 dubug 服务器或生产 wsgi 服务器! 当您尝试多进程或多线程时! 您应该使用不同的浏览器或 Chrome 隐身窗口!!!!

      解决我所有的问题! 示例代码在这里

      from flask import Flask
      import time
      import os
      import threading as td
      
      app = Flask(__name__)
      
      #trying  http://127.0.0.1:5000/
      @app.route('/')
      def index():
          print('index')
          print('pid:', os.getpid())
          print('thread id:', td.get_ident())
          time.sleep(10)
          return "Hello, World!"
      
      
      if __name__ == '__main__':
          app.run(host='0.0.0.0', port=5000, threaded=True)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-05-08
        • 2016-04-18
        • 2018-10-06
        • 1970-01-01
        • 2017-07-24
        • 2016-04-19
        • 1970-01-01
        相关资源
        最近更新 更多