【问题标题】:Threading an external script within a Flask app在 Flask 应用程序中线程化外部脚本
【发布时间】:2019-08-21 00:18:56
【问题描述】:

我有一个 Flask 应用程序,它使用外部脚本来执行某些操作。在其中一个脚本中,我使用threading 来运行线程。

我在实际线程中使用以下代码:

for a_device in get_devices:
    my_thread = threading.Thread(target=DMCA.do_connect, args=(self, a_device, cmd))
    my_thread.start()

main_thread = threading.currentThread()
for some_thread in threading.enumerate():
    if some_thread != main_thread:
        some_thread.join()

但是,当此脚本(从表单)运行时,该过程将挂起,我将在网页上获得一个连续的加载周期。
还有其他方法可以在应用程序中使用多线程吗?

【问题讨论】:

  • 脚本的密集程度如何?假设.join 逻辑是正确的(我不确定是不是),如果线程都忙了很长时间,main 将被阻塞。 main 是否需要等待结果才能响应请求?为什么前端不是异步的,至少可以防止客户端在响应准备好之前挂起?更多细节似乎是必要的。谢谢。
  • 也许您想让subprocess 派生一个子python 解释器?然后调度是解耦的。如果孩子的启动成本应该摊销,请考虑在初始请求完成后让孩子留在身边。
  • @ggorlen 使用线程的脚本连接到几个无线局域网控制器,并根据 x 向它们发送命令。作为一个独立的脚本,它大约需要 17 秒才能完成,而将它集成到 Flask 中,在没有线程的情况下所花费的时间与使用线程所花费的时间相同。 Flask 是否“保留”线程直到所有线程都完成,以便可以使用“结果”页面呈现它们?
  • CPython 是单线程的,所以使用多线程的主要原因是当你有任务阻塞 I/O 时。如果任务受 CPU 限制,请使用 J_H 所说的多处理。但归根结底,如果你有一个非常密集的任务(即使你没有),也没有任何理由强迫前端冻结。再次......关于整个堆栈的更多细节是必要的,但基本上,如果前端冻结,这是一个 JS 问题,而不是 Python 问题,即使你让 Flask 立即响应,仍然可能存在连接问题你不想冻结客户端。
  • 当你问“Flask 是否“保留”线程直到所有线程都完成以便可以使用“结果”页面呈现它们?听起来您正在从 Flask 提供 HTML。我会先提供一些 HTML,然后向后端发出一个 ajax 请求来执行这个昂贵的操作。这个异步请求将完成它的工作,客户端可以使用友好的消息/微调器来处理他们的业务,并且在响应到达等待页面加载之前不会冻结。一旦你解决了这个问题,你就可以开始优化你的 Python 脚本了。

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


【解决方案1】:

在 Flask 应用程序中自己实现线程对我来说总是以某种灾难告终。您可能想要使用分布式任务队列,例如Celery。尽管您可能很想自己分拆线程以更快地完成它,但您将开始面临各种问题,最终会浪费大量时间(恕我直言)。

Celery 是一个基于分布式的异步任务队列/作业队列 消息传递。它专注于实时操作,但支持 调度也是如此。

执行单元,称为任务,在一个 使用多处理、Eventlet 或 事件。任务可以异步执行(在后台)或 同步(等到准备好)。

这里有一些很好的资源可供您开始使用

【讨论】:

    猜你喜欢
    • 2018-07-28
    • 2013-05-04
    • 2020-06-17
    • 2016-05-07
    • 2020-09-07
    • 2021-02-15
    • 2015-12-16
    • 2016-07-25
    • 2021-11-09
    相关资源
    最近更新 更多