在调用Flask后,我可以使用Python代码继续执行app.run?

时间:2017-10-29 21:56:20

标签: python multithreading asynchronous flask

我刚刚开始使用Python,尽管在过去的30年里我一直使用其他语言进行编程。我想保持我的第一个应用程序简单,所以我开始在Raspberry Pi上托管一个小型家庭自动化项目。

我的代码工作正常(控制阀门,读取流量传感器并在显示器上显示一些数据),但是当我想添加一些网络交互时,它突然停止了。 我在该主题上发现的大多数文章都建议使用Flask框架来组成动态网页。我已经尝试并理解了Flask的基础知识,但是当我调用“app.run”函数时,我无法解决Flask阻塞的问题。我的其他python代码等待Flask返回,这从未发生过。即不再需要水流量测量,阀马达转向或显示更新。

所以,我的基本问题是:我应该使用什么工具来提供简单的动态网页(负载非常低,如1个请求/周),与我的应用程序主要任务(GPIO /脉冲计数)并行)?所有这些都在Raspberry Pi的资源受限环境中(3)。 如果您仍然建议使用Flask(因为它看起来非常接近目标),我应该如何安排我的代码来处理真实世界的事件,如上所述?

(最后一部分可能很难回答而没有看到实际代码,但也许它可能以“通用”的方式回答它?或指向我在搜索时可能错过的现有示例。)

3 个答案:

答案 0 :(得分:2)

您正在使用多线程进入正确的轨道。如果监控代码在循环中运行,则可以定义类似

的函数
def monitoring_loop():
    while True:
        # do the monitoring

然后,在调用app.run()之前,启动一个运行该函数的线程:

import threading
from wherever import monitoring_loop

monitoring_thread = threading.Thread(target = monitoring_loop)
monitoring_thread.start()

# app.run() and whatever else you want to do

不要join线程 - 您希望它与Flask应用并行运行。如果你加入它,它将阻止主执行线程,直到它完成,这将永远不会,因为它运行while True循环。

要在监视线程和程序的其余部分之间进行通信,您可以使用queue以线程安全的方式在它们之间传递消息。

答案 1 :(得分:0)

我可能会处理这个问题的方法是将程序拆分为两个不同的单独运行程序。

一个程序处理GPIO监视和通信,另一个程序是您的小型Flask服务器。由于它们作为单独的进程运行,因此它们不会相互阻塞。

您可以让这两个进程通过一个小型数据库进行通信。 GIPO接口可以定期将流量测量或其他相关数据记录到数据库中的表中。它还可以监视数据库中可能充当请求队列的另一个表。

您的Flask实例可以查询同一个数据库以获取当前统计信息以返回给用户,并可以根据用户输入将条目提交到请求队列。 (如果GIPO流程使用当前状态更新请求队列,则Flask流程可以报告退出。)

至于在一个小的Raspberry Pi上使用什么类型的数据库,请考虑sqlite3这是一个非常小,轻量级的基于文件的数据库,作为Python中的标准库得到很好的支持。 (它不需要运行完整的“数据库服务器”进程。)

祝你的项目好运,听起来很有趣!

答案 2 :(得分:0)

嗨,我正在尝试使用dronekit_sitl进行连接,但遇到同样的问题,在30秒后关闭了连接。要解决这个问题,有2种解决方案:

  1. 您使用装饰器 before_request :在此装饰器中,您将定义一个方法,该方法将在每次请求之前处理连接
  2. 您使用装饰器 before_first_request :在这种情况下,将在调用第一个请求后建立连接,并且您可以使用全局变量
  3. 处理其他路由中的对象

有关更多信息,https://pythonise.com/series/learning-flask/python-before-after-request