Flask使用线程异步执行耗时任务

flask+aiohttp实现异步协程来减少请求耗时 【代码】flask+aiohttp实现异步协程来减少请求耗时。 阅读详情

1 问题说明

1.1 任务简述

在开发Flask应用中一定会遇到执行耗时任务,但是Flask是轻量级的同步框架,即在单个请求时服务会阻被塞,直到任务完成(注意:当前请求被阻塞不会影响到其他请求)。

解决异步问题有两种思路,一种是借助外部工具实现异步,例如:消息队列(RabbitMQ)、 异步任务队列(Celery+Redis);另一种借助Python中的进程、线程或协程解决异步。我的是小项目选择因此选择了第二种方法。

经过测试,我在Flask中使用协程(gevent)会被阻塞;使用进程(multiprocessing)不会被阻塞,操作数据库出了问题(有可能是我没操作正确的问题);最后选择使用线程(threading)。

注意:使用线程会出现线程安全问题,

1.2 注意的问题

(1)线程安全

"""
!!! 注意
1 由于flask-SQLAlchemy对SQLAlchemy进行了封装,所以是线程安全的,可以在线程中直接使用;
2 原生SQLAlchemy中
        # 2.1 直接使用Session是线程不安全的,不推荐使用
        self.session = Session(self.engine)

        # 2.2 直接使用scoped_session是线程安全的,推荐使用
        # 获取sessionmaker
        session_factory = sessionmaker(engine)
        # scoped_session是线程安全的
        # 注意,此session不能使用Query对象
        session = scoped_session(session_factory)
        
!!!
"""

(2)使用数据库

# 注意:高版本的Flask-SQLAlchemy(我的版本Flask-SQLAlchemy==3.1.1,SQLAlchemy==2.0.16)必须使用”with app.app_context()“,本质原因是Flask关联的SQLAlchemy版本太高
# 否则无法插入数据库并报错,错误内容如下(低版本不会出现此问题):
"""
This typically means that you attempted to use functionality that needed
the current application. To solve this, set up an application context
with app.app_context(). See the documentation for more information.
"""

2 工程布局

项目布局如下:
在这里插入图片描述

3 源代码

(1)main.py

from blueprint import init_blueprint
from config_app import app
from config_db import init_mysql_db


# 初始化MySQL
init_mysql_db()

init_blueprint()

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

(2)config_app.py

from flask import Flask
from flask_cors import CORS


def create_app():
    flask_app = Flask(__name__)
    CORS(flask_app, supports_credentials=True)
    return flask_app


app = create_app()

(3)config_db.py


from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow

# 添加pymysql驱动,连接MySQL数据库
import pymysql

from config_app import app

pymysql.install_as_MySQLdb()

"""
!!! 注意
1 由于flask-SQLAlchemy对SQLAlchemy进行了封装,所以是线程安全的,可以在线程中直接使用;
2 原生SQLAlchemy中
        # 2.1 直接使用Session是线程不安全的,不推荐使用
        self.session = Session(self.engine)

        # 2.2 直接使用scoped_session是线程安全的,推荐使用
        # 获取sessionmaker
        session_factory = sessionmaker(engine)
        # scoped_session是线程安全的
        # 注意,此session不能使用Query对象
        session = scoped_session(session_factory)
        
!!!
"""

# 创建MySQL单实例
mysql_db = SQLAlchemy()

# 创建Schema
mysql_schema = Marshmallow()


# 创建数据库
"""
create database async default character set utf8mb4 collate utf8mb4_unicode_ci;
"""

class MysqlConf:
    acc = "root"
    pwd = "123456"
    host = "192.168.108.200"
    port = 3306
    db = "async"


mysql_conf = MysqlConf()


# 初始化MySQL数据库
def init_mysql_db():

    # 配置MySQL数据库url
    db_url = "mysql://" + mysql_conf.acc + ":" + mysql_conf.pwd + "@" + mysql_conf.host + ":" + str(mysql_conf.port) + "/" + mysql_conf.db
    app.config["SQLALCHEMY_DATABASE_URI"] = db_url

    # 关闭sqlalchemy自动跟踪数据库
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

    # 显示底层执行的SQL语句
    app.config['SQLALCHEMY_ECHO'] = True

    # 解决‘No application found. Either work inside a view function or push an application context.’
    app.app_context().push()

    # 初始化app
    mysql_db.init_app(app)

    # 初始化schema
    mysql_schema.init_app(app)


# 初始化table
def init_table():
    # 删除表
    mysql_db.drop_all()
    # 创建表
    mysql_db.create_all()

(4)dao.py

import datetime

from config_db import mysql_db as db


# Create table of bm_record
class User(db.Model):
    # Record table
    __tablename__ = "as_user"

    id = db.Column("us_id", db.Integer, nullable=False, primary_key=True, autoincrement=True)
    name = db.Column("us_name", db.String(100))
    age = db.Column("us_age", db.Integer)
    create_time = db.Column("us_create_time", db.DateTime, default=datetime.datetime.now)


# 插入数据
def insert_record_dao(user: User):
    # Add data
    db.session.add(user)
    # Commit data
    db.session.commit()

(5)blueprint.py

# 构建蓝本
import threading
import time
from concurrent.futures import ThreadPoolExecutor

from flask import Blueprint, jsonify

from config_app import app
from config_db import init_table
from dao import insert_record_dao, User

user = Blueprint("user", __name__)


# 注册蓝本
def init_blueprint():
    app.register_blueprint(user, url_prefix='/user')


@user.route("/initdb")
def init_db():
    init_table()
    return jsonify("success")


@user.route("/add")
def add_user():
    user: User = User()
    user.name = "zhangsan"
    user.age = 12

    time.sleep(10)
    insert_record_dao(user)

    return jsonify(user.id)


executor = ThreadPoolExecutor(3)
@user.route("/thread_pool")
def run_task_thread_pool():
    executor.submit(_run_thread_pool)
    return jsonify("success")


# 执行线程
def _run_thread_pool():
    print("Run thread pool")
    time.sleep(2)
    user: User = User()
    user.name = "thread pool"
    user.age = 12

    # 注意:必须使用”with app.app_context()“,否则无法插入数据库,并且不会报错
    with app.app_context():
        insert_record_dao(user)

    print("End thread pool")
    pass


@user.route("/thread")
def run_task_thread():
    task = threading.Thread(target=_run_thread, name='thread-01')
    task.start()

    return jsonify("success")


# 执行线程
def _run_thread():
    print("Run thread")
    time.sleep(2)

    user: User = User()
    user.name = "thread"
    user.age = 12

    # 注意:高版本的Flask-SQLAlchemy(我的版本Flask-SQLAlchemy==3.1.1,SQLAlchemy==2.0.16)必须使用”with app.app_context()“,本质原因是Flask关联的SQLAlchemy版本太高
    # 否则无法插入数据库并报错,错误内容如下(低版本不会出现此问题):
    """
    This typically means that you attempted to use functionality that needed
    the current application. To solve this, set up an application context
    with app.app_context(). See the documentation for more information.
    """
    with app.app_context():
        insert_record_dao(user)

    print("End thread")
    pass

4 请求截图

(1)初始化数据库

在这里插入图片描述

(2)添加用户

在这里插入图片描述

(3)使用线程池

在这里插入图片描述

(4)使用线程

在这里插入图片描述

python web: flask异步执行任务 摘要: Flask作为同步框架,处理耗时任务时需异步执行以避免阻塞。本文介绍了两种实现方式: 线程池:通过ThreadPoolExecutor快速实现异步任务,但需额外设计状态查询机制。 Celery:结合Redis作为消息队列,支持任务状态跟踪。通过@celery.task装饰器标记耗时函数,利用update_state()更新进度,并提供接口(如/status/<task_id>)供前端轮询状态。示例代码展示了进度条功能的实现,包括任务启动、状态返回(202状态码)及元数据传递。适用于邮件发 阅读详情

相关推荐

后台异步队列实现的简单示例(Flask)

在Web应用程序开发中,后台异步队列是一种常见的技术,用于处理耗时的任务,以免阻塞用户请求和响应。在本文中,我们将使用Flask框架来实现一个简单的后台异步队列示例,让您了解如何在Web应用程序中使用异步队列。首先,我们需要安装Flask和Celery库,Celery是一个强大的分布式任务队列框架,用于处理异步任务。,看到返回的任务ID。在上面的代码中,我们创建了一个Flask应用程序,并配置了Celery。路由函数中,我们将任务添加到异步队列中,并返回任务的ID。的异步任务函数,用于模拟一个耗时的任务。

RfqrScheme的博客 359

flask框架异步处理耗时任务

flask框架异步处理耗时任务 # 异步 executor = ThreadPoolExecutor(10) def run(): """ 函数run是耗时任务 :return: """ data = SQLTool().query('select * from physical_market') print(data) @pccarcityb...

DokcelyNg的博客 4938

Flask后端开发中的异步任务处理框架

在现代Web应用开发中,用户体验和系统性能至关重要。作为轻量级Python Web框架的代表,Flask以其简洁灵活的特性深受开发者喜爱。然而,当面临耗时操作(如邮件发送、数据处理、文件转换等)时,传统的同步处理方式会导致请求阻塞,严重影响用户体验。本文将深入探讨Flask后端开发中的异步任务处理机制,从核心概念解析到主流框架(Celery、RQ、Huey)的实战应用,帮助开发者构建高性能、响应迅速的Web应用。

架构师的AI之路,分享AI应用开发架构的学习与实践。 1134

Flask框架实现异步处理请求

Flask框架实现异步处理请求

IT之一小佬的博客 8778

使用Flask路由进行Python异步调用

在某些情况下,我们可能需要在Flask应用程序中执行异步任务,例如与外部API进行通信或执行耗时的操作。本文将介绍如何在Flask应用程序中使用异步调用,并提供相应的源代码示例。通过在应用程序中使用异步调用,我们可以实现与外部服务的异步通信,或者执行那些耗时的操作,而不会阻塞应用程序的响应性。接下来,我们将创建一个简单的Flask应用程序,并添加一个异步路由。然后,我们创建一个Flask应用程序,并定义了两个路由。这只是一个示例,用于展示基本的Flask路由。在上面的代码中,我们首先导入必要的库,并使用。

NfsVerilog的博客 629

flask-celery-ml:使用Celery在Flask应用程序中处理长时间运行的流程(例如ML模型预测)

在Flask应用中处理ML预测 由Austin Poor创建 此存储库演示了一种通过将Flask应用程序传递给Celery来处理长时间运行的过程(例如ML模型预测)的技术。 尽管这只是一个简单的示例,但是在执行缓慢而复杂的任务(例如进行ML预测,建立建议或更新数据库)时,相同的工作流程可能会有所帮助。 演示版 该应用程序由Redis(Celery的代理和后端),Celery工作者以及Flask应用程序组成。 Flask应用由一个简单HTML登陆页面和两个API端点组成。 HTML页面具有4个范围滑块,使您可以选择虹膜的萼片和花瓣的宽度和高度的值进行预测。 当您单击Submit按钮时,一个javascript函数会将POST请求中的参数发送到/api/predict ,后者使用Celery worker安排预测,并返回将存储结果的taskid 。 然后,在发出请求之后,浏览器将轮

flask 主线程返回,新线程来进行耗时任务的执行

项目中遇到需求,前端返回结果,后端进行比较耗时的操作。例如判断某客户ID是否在远程数据库。根据ID查询远程数据库,如果不存在,在前端提示客户不存在;如果存在,则前端提示客户存在,后端将根据客户ID,查询远程数据库的其他表,并将查询到的信息插入到本地数据库。 本来没有想到多线程,只想着如何在return返回给前端信息之后再进行耗时操作,但在后端试了很多方法,都不能实现效果。后面又想到在前端click事件上增加一个新方法,虽然功能实现了,但前端同学表示,并不想增加新方法,而且个人觉得这样实现很别扭。 随后想

caorya的博客 2961

CTF密码学奇技淫巧:当Base64遇到ROT13与Atbash

本文深入解析CTF竞赛中Base64、ROT13与Atbash的复合编码技术,提供Python实现与CyberChef可视化处理方案,帮助选手掌握密码学题目的解题技巧。通过NewStarCTF2025实战案例,对比脚本化与可视化工具的优劣,提升Web安全竞赛中的编码处理能力。

weixin_29001683的博客 509

python2处理耗时任务_Python Web:Flask 异步执行任务

简介Flask 是 Python 中有名的轻量级同步 web 框架,在一些开发中,可能会遇到需要长时间处理的任务,此时就需要使用异步的方式来实现,让长时间任务在后台运行,先将本次请求的响应状态返回给前端,不让前端界面「卡顿」,当异步任务处理好后,如果需要返回状态,再将状态返回。怎么实现呢?使用线程的方式当要执行耗时任务时,直接开启一个新的线程来执行任务,这种方式最为简单快速。通过 ThreadPo...

weixin_39526185的博客 276

水下探测小白必看:单波束vs多波束声呐,5分钟搞懂核心区别

本文为水下探测新手清晰解析了单波束与多波束声呐的核心区别。单波束声呐如同精准的“手电筒”,进行逐点扫描,适用于定点测深和目标探测;而多波束声呐则像“聚光灯”,能一次性覆盖一个扇区,高效获取海底地形三维信息,是海底测绘和水下三维建模的理想选择。文章通过生动的比喻和对比表格,帮助读者快速理解两者原理、效率差异及适用场景。

linux6sysadmin的博客 1050

【免费】最新区块链钱包和私钥的助记词碰撞器,bybit使用python开发

【免费】最新助记词钱包碰撞器,全链全网络,一周左右就有,稳定高效。

weixin_48529185的博客 1万+

python2处理耗时任务_Python Web:Flask异步执行任务

(▲由Python大本营付费下载自视觉中国)作者 | ayuliao 出自 | hackpython(ID:hackpython)简介Flask 是 Python 中有名的轻量级同步 web 框架,在一些开发中,可能会遇到需要长时间处理的任务,此时就需要使用异步的方式来实现,让长时间任务在后台运行,先将本次请求的响应状态返回给前端,不让前端界面「卡顿」,当异步任务处理好后,如果需要返回...

weixin_29161719的博客 649

Ardupilot姿态控制详解(完结篇)

本文主要是对过去写的一些APM中姿态控制流程及函数博文的汇总。 按照之前写的博文以及个人认为的学习顺序,给出APM姿态控制器的学习顺序如下: APM姿态旋转理论基础 Ardupilot姿态控制器 PID控制流程(整定后的P控制器) 详解APM的开方控制器sqrt_controller Ardupilot前馈及平滑函数input_euler_angle_roll_pitch_yaw解析 Ardupilot倾转分离函数thrust_heading_rotation_angles Ardupilot四元数姿态控制

moumde的博客 7025

flask异步执行linux命令_Flask中简单实现异步任务,非常实用的小技巧

众所周知Flask默认不能很好的完成异步任务,那么我们如何在请求中快速返回状态并异步执行比较复杂耗时的任务呢?话不多说看实现。用到了ThreadPoolExecutor类初始化线程池(这里初始化了10个线程)from flask import Flaskfrom concurrent.futures import ThreadPoolExecutorexecutor = ThreadPoolExe...

weixin_36241447的博客 259

(王道计算机组成原理)第二章数据的表示和运算-第三节:运算方法和运算电路 1(基本运算部件)

本文主要介绍了计算机组成原理中的加法器和算术逻辑单元(ALU)的基本概念与实现原理。首先,文章详细讲解了一位全加器的工作原理,包括其输入输出、逻辑表达式及真值表。接着,介绍了并行加法器的两种类型:串行进位和并行进位的加法器,分析了它们的优缺点。随后,文章探讨了带标志位的加法器,说明了如何通过标志位生成逻辑来判断加法结果的状态。最后,文章阐述了ALU的功能及其实现原理,包括ALU的基本结构、控制信号的作用以及在实际考试中的图示表示。通过这些内容,读者可以全面了解加法器和ALU在计算机中的重要作用及其工作原理。

快乐江湖的博客 3837

VTK-9.5.0 1D2D3DWidget实现灰度图+深度图+3D点云显示(可轻松集成到自己的项目)

VTK1D2D3DWidget是一个基于Qt和VTK开发的3D点云可视化工具,支持RGB和深度点云数据的显示与处理。主要功能包括点云加载、可视化、保存为PLY格式文件,以及背景颜色、点间隔、坐标轴显示等参数的自定义设置。该工具采用模块化设计,核心组件包括主窗口管理类、VTK渲染组件和自定义鼠标交互样式,依赖Qt5+和VTK9.5.0库实现跨平台支持。项目提供完整的源码和构建指南,适用于点云数据的快速展示与分析。

Qt历险记,专注Qt技术,三年医疗设备研发经验,1年机器视觉研发经验,半年柔性传感研发经验。 389

apply_async进程不执行_Python Web:Flask 异步执行任务

原创: ayuliao 源:hackPython简介Flask 是 Python 中有名的轻量级同步 web 框架,在一些开发中,可能会遇到需要长时间处理的任务,此时就需要使用异步的方式来实现,让长时间任务在后台运行,先将本次请求的响应状态返回给前端,不让前端界面「卡顿」,当异步任务处理好后,如果需要返回状态,再将状态返回。怎么实现呢?使用线程的方式当要执行耗时任务时,直接开启一个新的线程来执行任...

weixin_29383429的博客 603

VAY 是 SAP 自动科目确定(OBYC-GBB)中的科目修改码,专用于带科目分配对象的销售订单发货场景,核心是触发 “Dr 成本要素科目(如销售费用 / 特定成本对象) Cr 库存商品” 的分录,

摘要:VAY是SAP中用于带科目分配对象(如成本中心、WBS)的销售订单发货的科目修改码,与标准VAX场景不同,它生成"借成本要素科目/贷库存商品"的分录。配置路径为OBYC-GBB-VAY,需确保借方科目为成本要素。典型业务场景包括免费样品、项目专用发货等。常见问题包括VAY未触发或科目记账错误,需检查销售订单科目分配、移动类型设置及OBYC配置。特殊场景建议单独配置科目以便费用分析。

金牌架构师 1257

python进度条 装饰器_Python Web:Flask异步执行任务

Flask 是 Python 中有名的轻量级同步 web 框架,在一些开发中,可能会遇到需要长时间处理的任务,此时就需要使用异步的方式来实现,让长时间任务在后台运行,先将本次请求的响应状态返回给前端,不让前端界面「卡顿」,当异步任务处理好后,如果需要返回状态,再将状态返回。怎么实现呢?使用线程的方式当要执行耗时任务时,直接开启一个新的线程来执行任务,这种方式最为简单快速。通过 ThreadPool...

weixin_39779530的博客 742

【硬件】LT3763中文手册

1)精确控制输入和输出电流;2) 3000:1真彩色PWM™调光;3) ±1.5%电压调节精度;4) ±6%电流调节精度;5)6V至60 V输入电压范围;6)宽输出范围最高可达55V;7)<2µA关断电流;8)用于负载电流热控制的控制引脚;9)输入和输出电流监控和限制;10)开路、短路和C/10故障检测;11)适用于LED应用的PWM驱动器输出;12)热增强型28引脚FE封装。

qq_39200110的博客 491

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

flask实现异步任务

flask实现异步任务 最近在开发同步mysql数据到redis的接口,因为数据同步涉及各种增删查改,如果用同步实现,可能回造成连接超时、堵塞,所以,使用python实现异步任务。 代码实现 from flask import Flask import time from concurrent.futures import ThreadPoolExecutor executor = Thread...

panyuteng的博客 3万+

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Flask实现异步任务

代码实现: from flask import Flask from concurrent.futures import ThreadPoolExecutor import time executor = ThreadPoolExecutor(1) app = Flask(__name__) @app.route("/synchronize") def update_redis(): ...

weixin_34050427的博客 658

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

python进度条 装饰器_2种方式解决Python执行卡顿问题

简介Flask 是 Python 中有名的轻量级同步 web 框架,在一些开发中,可能会遇到需要长时间处理的任务,此时就需要使用异步的方式来实现,让长时间任务在后台运行,先将本次请求的响应状态返回给前端,不让前端界面「卡顿」,当异步任务处理好后,如果需要返回状态,再将状态返回。怎么实现呢?使用线程的方式当要执行耗时任务时,直接开启一个新的线程来执行任务,这种方式最为简单快速。通过 ThreadPo...

weixin_39880666的博客 323

python 异步

【代码】python 异步。

xkx_07_10的博客 214
上一篇: ChatGLM3-6B安装
下一篇: Flask和Vue框架实现WebSocket消息通信
MasonYyp
博客等级 码龄9年 301粉丝 297原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值