python利用多线程让http请求异步返回

news2025/2/28 23:59:48

嗨喽~大家好呀,这里是魔王呐 ❤ ~!

python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取

有时我们可能会碰到这样一种情况:

我们有一个功能,这个功能对外提供了一个http接口,

我们需要对这个http接口发起请求才能启动这个服务,

但是这个服务功能可能会执行很久,这样如果等功能执行结束再返回请求结果,

那这个请求可能就超时了

发起请求的客户端

 import requests
  
 req = requests.get("http://127.0.0.1:9898/register?username=aaa&pwd=232323")
 print(req.content)

服务端

# coding=utf-8
import flask
from flask import jsonify
from flask import request

from gevent import pywsgi

import sys
reload(sys)
import time
sys.setdefaultencoding('utf-8')

server = flask.Flask(__name__)
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:926207505
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
@server.route('/register', methods=['get', 'post'])
def registerPost():
    # post请求获取请求的参数,返回结果类型是str
    username = request.values.get('username')
    pwd = request.values.get('pwd')
    app_id = request.values.get('app_id')
    dowork(app_id)
    # confirmpwd = request.values.get('confirmpwd')
    if username and pwd:  # 判断输入的用户名、密码、确认密码都不为空
        return ("用户名为:%s, 密码为:%s" % (username, pwd))
    else:
        return jsonify({"code": 504, "msg": "必填项不能为空"})


if __name__ == '__main__':
    # port可以指定端口,默认端口是5000
    # host默认是127.0.0.1,写成0.0.0.0的话,其他人可以访问,代表监听多块网卡上面,
    # server.run(debug=True, port=9898, host='0.0.0.0')
    server = pywsgi.WSGIServer(('0.0.0.0', 9898), server)
    server.serve_forever()

这个就是一个典型的同步返回结果,

发起请求后,必须等 dowork() 功能执行完之后才能返回请求结果,

如果 dowork() 执行时间较长,则会导致客户端请求超时

这时我们可能就需要一个异步的http接口,收到客户端的请求后,马上返回一个请求结果,然后再慢慢的执行要执行的任务,这个过程怎么实现呢?

我的做法是通过多线程来实现,

在服务端的响应函数中,每次收到一个请求,获取请求中携带的参数,

然后用这些参数创建一个会执行我们功能服务的线程,

最后返回请求结果,这样客户端可以很快获取到请求结果,从而不会让客户端请求超时

下面是加入了线程的服务端的响应函数

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:926207505
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
import flask
from flask import jsonify
from flask import request

from gevent import pywsgi

import sys
reload(sys)
import time
sys.setdefaultencoding('utf-8')

server = flask.Flask(__name__)

import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter, app_id):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
        self.app_id = app_id
    def run(self):
        print ("开始线程:" + self.name)
        print_time(self.name, self.counter, 1, self.app_id)
        print ("退出线程:" + self.name)

def print_time(threadName, delay, counter, app_id):
    while counter:
        if exitFlag:
            threadName.exit()
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        dowork(app_id)
        counter -= 1

@server.route('/register', methods=['get', 'post'])
def registerPost():
    # post请求获取请求的参数,返回结果类型是str
    username = request.values.get('username')
    pwd = request.values.get('pwd')
    app_id = request.values.get('app_id')

    # 创建新线程
    thread1 = myThread(1, "Thread-1", 1, app_id)
    # 开启新线程
    thread1.start()

    # confirmpwd = request.values.get('confirmpwd')
    if username and pwd:  # 判断输入的用户名、密码、确认密码都不为空
        return ("用户名为:%s, 密码为:%s" % (username, pwd))
    else:
        return jsonify({"code": 504, "msg": "必填项不能为空"})


if __name__ == '__main__':
    # port可以指定端口,默认端口是5000
    # host默认是127.0.0.1,写成0.0.0.0的话,其他人可以访问,代表监听多块网卡上面,
    # server.run(debug=True, port=9898, host='0.0.0.0')
    server = pywsgi.WSGIServer(('0.0.0.0', 9898), server)
    server.serve_forever()

因为线程的run()方法和start()方法是不能传递参数的,

所以如果我们需要从请求中获取参数然后传递给要执行的功能的话,

可以在线程的构造方法的参数中加上我们需要传递的参数,

这样在run()方法内部我们就能动态获得请求中传递的参数了

下面是菜鸟教程里面的多线程模板

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:926207505
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
import threading
import time

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print ("开启线程: " + self.name)
        # 获取锁,用于线程同步
        threadLock.acquire()
        print_time(self.name, self.counter, 3)
        # 释放锁,开启下一个线程
        threadLock.release()

def print_time(threadName, delay, counter):
    while counter:
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

threadLock = threading.Lock()
threads = []

# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()

# 添加线程到线程列表
threads.append(thread1)
threads.append(thread2)

# 等待所有线程完成
for t in threads:
    t.join()
print ("退出主线程")

执行以上程序,输出结果为:

开启线程: Thread-1
开启线程: Thread-2
Thread-1: Wed Apr  6 11:52:57 2016
Thread-1: Wed Apr  6 11:52:58 2016
Thread-1: Wed Apr  6 11:52:59 2016
Thread-2: Wed Apr  6 11:53:01 2016
Thread-2: Wed Apr  6 11:53:03 2016
Thread-2: Wed Apr  6 11:53:05 2016

尾语

最后感谢你观看我的文章呐~本次航班到这里就结束啦 🛬

希望本篇文章有对你带来帮助 🎉,有学习到一点知识~

躲起来的星星🍥也在努力发光,你也要努力加油(让我们一起努力叭)。

最后,宣传一下呀~👇👇👇更多源码、资料、素材、解答、交流皆点击下方名片获取呀👇👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1094283.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Liunx中日志分析与网络设置(极其粗糙版)

liunx系统日志的管理 系统日志:操作系统本身和大部分服务器程序的日志文件 日志是记录系统所产生的各种事故,在某个时间节点发生了什么,发生的原因 liunx的路径是/var/log下 /var/log/messages:内核日志还有公共信息日志(所有…

冒泡排序(学习笔记)

冒泡排序(基于交换的排序,每一轮确定一个数的位置) 哨兵举例: 待排序序列:6 3 1 2 5 第一轮排列: 3 6 1 2 5 3 1 6 2 5 3 1 2 6 5 3 1 2 5 6(最大的数移动到了正确的位置) 第二轮排列…

Mall脚手架总结(五) —— SpringBoot整合MinIO实现文件管理

前言 在项目中我们经常有资源的上传和下载的功能需求,比如用户头像、产品图片、配置文件等等,大数据量的文件存储无疑需要更高性能的数据存储服务,对于无需对结构实现复杂查询的文件对象来说,对象存储服务无疑是一个较好的选择&am…

并查集路径压缩

我们来看看如果要是100个数,往20个数的集合合并如何 那么我们应该,把数据量小的集合往数据量大的合并 解决另一种极端场景的路径压缩

限制条件加入构造范围:Gym - 102832L

https://vjudge.net/contest/587311#problem/D 场上列方程求首项,假设是全部加1,然后一部分(后缀)减去 k 1 k1 k1,就用到了以下两个条件: 但在这两种情况符合情况下,这个条件不一定满足 然后…

【软件测试】 初识软件测试

文章目录 🌴什么是软件测试🎋软件测试和开发的区别🚩软件测试与调试的区别 🌳软件测试的发展🎄软件测试岗位🍀软件测试在不同类型公司的定位🎍一个优秀的软件测试人员具备的素质🌲软…

105AspectRatio调整宽高比组件_flutter

AspectRatio组件 AspectRatio 的作用是根据设置调整子元素 child 的宽高比。 AspectRatio 首先会在布局限制条件允许的范围内尽可能的扩展,widget 的高度是由宽 度和比率决定的,类似于 BoxFit 中的 contain,按照固定比率去尽量占满区域。 …

【Redis】Java Spring操作redis

目录 引入Redis依赖StringRedisTemplate使用String使用List使用Set使用hash使用zset 引入Redis依赖 StringRedisTemplate 此处RedisTemplate是把这些操作Redis的方法,分成了几个类别,分门别类的来组织的。 此处提供的一些接口风格,和原生的Re…

利达卓越:发挥金融力量,促进团队发展

随着中国经济的快速增长和金融改革的逐步深化,我国金融业取得了令人瞩目的发展。作为经济的重要支柱,我国金融业的规模和实力不断扩大,已经成为全球最大的金融市场之一。利达卓越是一支由管理精英组成的团队,专注于金融行业的投资…

Empowering Low-Light Image Enhancer through Customized Learnable Priors 论文阅读笔记

中科大、西安交大、南开大学发表在ICCV2023的论文,作者里有李重仪老师和中科大的Jie Huang(ECCV2022的FEC CVPR2022的ENC和CVPR2023的ERL的一作)喔,看来可能是和Jie Huang同一个课题组的,而且同样代码是开源的&#xf…

解密人工智能:KNN | K-均值 | 降维算法 | 梯度Boosting算法 | AdaBoosting算法

文章目录 一、机器学习算法简介1.1 机器学习算法包含的两个步骤1.2 机器学习算法的分类 二、KNN三、K-均值四、降维算法五、梯度Boosting算法和AdaBoosting算法六、结语 一、机器学习算法简介 机器学习算法是一种基于数据和经验的算法,通过对大量数据的学习和分析&…

数据结构与算法-(8)---队列(Queue)

🌈write in front🌈 🧸大家好,我是Aileen🧸.希望你看完之后,能对你有所帮助,不足请指正!共同学习交流. 🆔本文由Aileen_0v0🧸 原创 CSDN首发🐒 如…

若依 ruoyi 路径 地址 # 井号去除

export default new Router({mode: history, // history 去掉url中的# 、hash 包含#号scrollBehavior: () > ({ y: 0 }),routes: constantRoutes })

嘉立创专业版新建元件

以2*24(2mm)排母为例 文件-新建-元件 新建器件 填上元件的基本信息,保存 选择库设计 填好参数,生成符号 给元件添加封装 需要先设计一个封装 选择header-V 填写参数,生成符号 保存即可。 再次进入元件的封装管理…

207、SpringBoot 整合 RabbitMQ 实现消息的发送 与 接收(监听器)

目录 ★ 发送消息★ 创建队列的两种方式代码演示需求1:发送消息1、ContentUtil 先定义常量2、RabbitMQConfig 创建队列的两种方式之一:配置式:问题: 3、MessageService 编写逻辑PublishController 控制器application.properties 配…

抖音开放平台第三方代小程序开发,授权事件、消息与事件通知总结

大家好,我是小悟 关于抖音开放平台第三方代小程序开发的两个事件接收推送通知,是开放平台代小程序实现业务的重要功能。 授权事件推送和消息与事件推送类型都以Event的值判断。 授权事件推送通知 授权事件推送包括:推送票据、授权成功、授…

java 基础 IO字符流

1.汉字存储占多少字节: public class IoTest {public static void main(String[] args) {String str "abcd";String str1 "吴危险学java";System.out.println("字符串转为byte数组:" Arrays.toString(str.getBytes())…

C# RestoreFormer 图像修复

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms;namespace 图像修复 {pu…

Python Opencv实践 - 车辆统计(1)读取视频,移除背景,做预处理

示例中的图像的腐蚀、膨胀和闭运算等需要根据具体视频进行实验得到最佳效果。代码仅供参考。 import cv2 as cv import numpy as np#读取视频文件 video cv.VideoCapture("../../SampleVideos/Traffic.mp4") FPS 10 DELAY int(1000 / FPS) kernel cv.getStructu…

【Jenkins使用】Jenkins 与 Git

一、概述 Jenkins 与 Git 的结合使用,可以理解为是 Jenkins 的一个强大之处。为什么要这么说,简要说明一下这个工作模式就能理解: 一个软件项目,开发过程中通常都会使用到一些源码管理工具,来达到团队协作的目的。而 …