简体   繁体   English

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

[英]Can I have Python code to continue executing after I call Flask app.run?

I have just started with Python, although I have been programming in other languages over the past 30 years.我刚刚开始使用 Python,尽管在过去的 30 年里我一直在使用其他语言进行编程。 I wanted to keep my first application simple, so I started out with a little home automation project hosted on a Raspberry Pi.我想让我的第一个应用程序保持简单,所以我从一个托管在 Raspberry Pi 上的小型家庭自动化项目开始。

I got my code to work fine (controlling a valve, reading a flow sensor and showing some data on a display), but when I wanted to add some web interactivity it came to a sudden halt.我的代码可以正常工作(控制阀门、读取流量传感器并在显示器上显示一些数据),但是当我想添加一些网络交互时,它突然停止了。 Most articles I have found on the subject suggest to use the Flask framework to compose dynamic web pages.我在这个主题上找到的大多数文章都建议使用 Flask 框架来组成动态网页。 I have tried, and understood, the basics of Flask, but I just can't get around the issue that Flask is blocking once I call the "app.run" function.我已经尝试并理解了 Flask 的基础知识,但是一旦我调用“app.run”函数,我就无法解决 Flask 阻塞的问题。 The rest of my python code waits for Flask to return, which never happens.我的其余 python 代码等待 Flask 返回,这从未发生过。 Ie no more water flow measurement, valve motor steering or display updating.即不再有水流量测量、阀门马达转向或显示更新。

So, my basic question would be: What tool should I use in order to serve a simple dynamic web page (with very low load, like 1 request / week), in parallel to my applications main tasks (GPIO/Pulse counting)?所以,我的基本问题是:在我的应用程序主要任务(GPIO/脉冲计数)的同时,我应该使用什么工具来提供简单的动态网页(负载非常低,例如 1 个请求/周)? All this in the resource constrained environment of a Raspberry Pi (3).所有这一切都在 Raspberry Pi (3) 的资源受限环境中完成。 If you still suggest Flask (because it seems very close to target), how should I arrange my code to keep handling the real-world events, such as mentioned above?如果你仍然建议 Flask(因为它看起来非常接近目标),我应该如何安排我的代码来继续处理现实世界的事件,比如上面提到的?

(This last part might be tough answering without seeing the actual code, but maybe it's possible answering it in a "generic" way? Or pointing to existing examples that I might have missed while searching.) (在没有看到实际代码的情况下,这最后一部分可能很难回答,但也许可以以“通用”方式回答它?或者指出我在搜索时可能遗漏的现有示例。)

You're on the right track with multithreading.你在多线程的正确轨道上。 If your monitoring code runs in a loop, you could define a function like如果您的监控代码循环运行,您可以定义一个函数,如

def monitoring_loop():
    while True:
        # do the monitoring

Then, before you call app.run() , start a thread that runs that function:然后,在调用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

Don't join the thread - you want it to keep running in parallel to your Flask app.不要join线程 - 您希望它与 Flask 应用程序保持并行运行。 If you joined it, it would block the main execution thread until it finished, which would be never, since it's running a while True loop.如果你加入它,它会阻塞主执行线程直到它完成,这永远不会,因为它正在运行一个while True循环。

To communicate between the monitoring thread and the rest of the program, you could use a queue to pass messages in a thread-safe way between them.要在监控线程和程序的其余部分之间进行通信,您可以使用队列以线程安全的方式在它们之间传递消息。

The way I would probably handle this is to split your program into two distinct separately running programs.我可能会处理这个问题的方法是将您的程序分成两个不同的单独运行的程序。

One program handles the GPIO monitoring and communication, and the other program is your small Flask server.一个程序处理 GPIO 监控和通信,另一个程序是您的小型 Flask 服务器。 Since they run as separate processes, they won't block each other.由于它们作为单独的进程运行,因此它们不会相互阻塞。

You can have the two processes communicate through a small database.您可以让两个进程通过一个小型数据库进行通信。 The GIPO interface can periodically record flow measurements or other relevant data to a table in the database. GIPO 接口可以定期将流量测量或其他相关数据记录到数据库中的表格中。 It can also monitor another table in the database that might serve as a queue for requests.它还可以监视数据库中可能用作请求队列的另一个表。

Your Flask instance can query that same database to get the current statistics to return to the user, and can submit entries to the requests queue based on user input.您的 Flask 实例可以查询同一个数据库以获取当前统计信息返回给用户,并且可以根据用户输入将条目提交到请求队列。 (If the GIPO process updates that requests queue with the current status, the Flask process can report that back out.) (如果 GIPO 进程使用当前状态更新请求队列,Flask 进程可以将其报告回来。)

And as far as what kind of database to use on a little Raspberry Pi, consider sqlite3 which is a very small, lightweight file-based database well supported as a standard library in Python.至于在小型 Raspberry Pi 上使用什么样的数据库,请考虑sqlite3 ,它是一个非常小的、轻量级的基于文件的数据库,作为 Python 中的标准库得到了很好的支持。 (It doesn't require running a full "database server" process.) (它不需要运行完整的“数据库服务器”进程。)

Good luck with your project, it sounds like fun!祝你的项目好运,听起来很有趣!

Hi i was trying the connection with dronekit_sitl and i got the same issue , after 30 seconds the connection was closed.To get rid of that , there are 2 solutions:嗨,我正在尝试与dronekit_sitl 建立连接,但我遇到了同样的问题,30 秒后连接关闭。要摆脱这种情况,有两种解决方案:

  1. You use the decorator before_request :in this one you define a method that will handle the connection before each request您使用装饰器before_request :在这个装饰器中,您定义了一个方法,该方法将在每个请求之前处理连接
  2. You use the decorator before_first_request : in this case the connection will be made once the first request will be called and the you can handle the object in the other route using a global variable您使用装饰器before_first_request :在这种情况下,将在调用第一个请求后建立连接,您可以使用全局变量处理另一条路由中的对象

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM