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

news/2024/7/19 9:48:12 标签: python, http, 开发语言, pycharm, 爬虫
http://www.w3.org/2000/svg" style="display: none;">

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

https://img-blog.csdnimg.cn/6b61cf3d76564ea3b93e2189e1f48d18.gif" alt="" />

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

尾语

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

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

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

https://img-blog.csdnimg.cn/3aa4cb754c0a43fba6d4bf5b2e73fb77.gif" alt="" />

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


http://www.niftyadmin.cn/n/5091041.html

相关文章

Vue3 + Nodejs 实战 ,文件上传项目--实现文件批量上传(显示实时上传进度)

目录 技术栈 1.后端接口实现 2.前端实现 2.1 实现静态结构 2.2 整合上传文件的数据 2.3 实现一键上传文件 2.4 取消上传 博客主页:専心_前端,javascript,mysql-CSDN博客 系列专栏:vue3nodejs 实战--文件上传 前端代码仓库:jiangjunjie…

上海市青少年算法2023年9月月赛(丙组)

上海市青少年算法2023年9月月赛(丙组) T1 口令的分类 题目描述 给定一串字符序列,请检查它是否符合成为口令的条件,并判断它的强弱。一个合规的口令,需要满足以下两个必要条件: 长度至少为 8,至多为 16。 只包含以下类型的字符 大写字母。 小写字母。 数字。 标点符号。…

分析谐波失真

目录 简介 查看非线性的影响 量化非线性失真 降低谐波失真的输入衰减 SNR THD 和 SINAD 当作输入衰减的函数 用于消除失真的后处理 组合方法 总结 此示例说明如何分析在具有噪声的情况下弱非线性系统的谐波失真。 简介 在此示例中,我们将研究放大器的简化模…

解决:由于找不到 VCRUNTIME140_.dll,无法继续执行代码。重新安装程序可能会解决此问题

最近我在安装一个软件时,遇到过这样的问题“由于找不到 VCRUNTIME140 1.dll,无法继续执行代码。重新安装程序可能会解决此问题”。 要解决这个问题,你可以按照以下步骤进行操作: 1. 重新安装程序: 尝试重新安装使用…

RISCV学习(2)玄铁C910处理器体验

笔者有幸参加了平头哥RISCV开发者大赛,体验了一下基于玄铁C910内核的矽速开发板。 1、开发板介绍 LicheePi 4A 是基于 Lichee Module 4A 核心板的 高性能 RISC-V Linux 开发板。 TH1520 为主控核心(4xC9101.85G, RV64GCV,4TOPSi…

数据库管理-第109期 19c OCM考后感(20231015)

数据库管理-第109期 19c OCM考后感(202301015) 距离上一篇又过了两周多,为啥又卡了这么久,主要是后面几个问题:1. 9月1日的19c OCM upgrade考试木有过,因为有一次免费补考机会就又预约了10月8日的考试&…

36.树与二叉树练习(2)(王道第5章综合练习)

试题1(王道5.3.3节第16题): 设计算法将二叉树的叶结点按从左到右的顺序连成单链表,连接时使用叶结点的右指针域存放单链表指针。 借助遍历算法完成: //根据二叉树层次遍历序列构造单链表 void LevelOrdertoLinkList…

2023-2024-1 for循环-1(15-38)

7-15 输出闰年 输出21世纪中截止某个年份以来的所有闰年年份。注意:闰年的判别条件是该年年份能被4整除但不能被100整除、或者能被400整除。 输入格式: 输入在一行中给出21世纪的某个截止年份。 输出格式: 逐行输出满足条件的所有闰年年份,即每个年…