Django如何使用asyncio协程和ThreadPoolExecutor多线程


Posted in Python onOctober 12, 2020

Django视图函数执行,不在主线程中,直接loop = asyncio.new_event_loop()
# 不能loop = asyncio.get_event_loop() 会触发RuntimeError: There is no current event loop in thread

因为asyncio程序中的每个线程都有自己的事件循环,但它只会在主线程中为你自动创建一个事件循环。所以如果你asyncio.get_event_loop在主线程中调用一次,它将自动创建一个循环对象并将其设置为默认值,但是如果你在一个子线程中再次调用它,你会得到这个错误。相反,您需要在线程启动时显式创建/设置事件循环:

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

在Django单个视图中使用asyncio实例代码如下(有多个IO任务时)

from django.views import View
import asyncio
import time
from django.http import JsonResponse
 
 
class TestAsyncioView(View):
  def get(self, request, *args, **kwargs):
    """
    利用asyncio和async await关键字(python3.5之前使用yield)实现协程
    """
    self.id = 5
    start_time = time.time()
 
    '''
    # 同步执行
    # results = [self.io_task1(self.id),
    # self.io_task2(self.id),
    # self.io_task2(self.id)]
    '''
 
 
    loop = asyncio.new_event_loop() # 或 loop = asyncio.SelectorEventLoop()
    asyncio.set_event_loop(loop)
    self.loop = loop
 
    works = [
      asyncio.ensure_future(self.io_task3(5)),
      asyncio.ensure_future(self.io_task3(5)),
      asyncio.ensure_future(self.io_task3(5)),
      asyncio.ensure_future(self.io_task3(5)),
      asyncio.ensure_future(self.io_task3(5)),
 
    ]
 
    try:
 
      results = loop.run_until_complete(asyncio.gather(*works)) # 两种写法
      # results = loop.run_until_complete(self.gather_tasks())
    finally:
      loop.close()
    end_time = time.time()
    return JsonResponse({'results': results, 'cost_time': (end_time - start_time)})
 
  async def gather_tasks(self):
 
    tasks = (
      self.make_future(self.io_task1, self.id),
      self.make_future(self.io_task2, self.id),
      self.make_future(self.io_task2, self.id),
      self.make_future(self.io_task1, self.id),
      self.make_future(self.io_task2, self.id),
      self.make_future(self.io_task2, self.id),
    )
    results = await asyncio.gather(*tasks)
    return results
 
  async def make_future(self, func, *args):
    future = self.loop.run_in_executor(None, func, *args)
    response = await future
    return response
 
  def io_task1(self, sleep_time):
    time.sleep(sleep_time)
    return 66
 
  def io_task2(self, sleep_time):
    time.sleep(sleep_time)
    return 77
 
  async def io_task3(self, sleep_time):
    # await asyncio.sleep(sleep_time)
    s = await self.do(sleep_time)
    return s
 
  async def do(self, sleep_time):
    await asyncio.sleep(sleep_time)
    return 66

在Django单个视图中使用ThreadPoolExecutor实例代码如下(有多个IO任务时)

from django.views import View
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
 
 
class TestThreadView(View):
  def get(self, request, *args, **kargs):
    start_time = time.time()
    future_set = set()
    tasks = (self.io_task1, self.io_task2, self.io_task2, self.io_task1, self.io_task2, self.io_task2)
    with ThreadPoolExecutor(len(tasks)) as executor:
      for task in tasks:
        future = executor.submit(task, 5)
        future_set.add(future)
    for future in as_completed(future_set):
      error = future.exception()
      if error is not None:
        raise error
    results = self.get_results(future_set)
    end_time = time.time()
    return JsonResponse({'results': results, 'cost_time': (end_time - start_time)})
 
  def get_results(self, future_set):
 
    results = []
    for future in future_set:
      results.append(future.result())
    return results
 
  def io_task1(self, sleep_time):
    time.sleep(sleep_time)
    return 66
 
  def io_task2(self, sleep_time):
    time.sleep(sleep_time)
    return 77

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python计算两个日期相差天数的方法示例
May 23 Python
详解使用 pyenv 管理多个版本 python 环境
Oct 19 Python
python3 遍历删除特定后缀名文件的方法
Apr 23 Python
python去除拼音声调字母,替换为字母的方法
Nov 28 Python
用Python获取摄像头并实时控制人脸的实现示例
Jul 11 Python
python构建指数平滑预测模型示例
Nov 21 Python
python从zip中删除指定后缀文件(推荐)
Dec 05 Python
Keras之fit_generator与train_on_batch用法
Jun 17 Python
python爬虫用mongodb的理由
Jul 28 Python
PyQt实现计数器的方法示例
Jan 18 Python
Django cookie和session的应用场景及如何使用
Apr 29 Python
python DataFrame中stack()方法、unstack()方法和pivot()方法浅析
Apr 06 Python
使用Python中tkinter库简单gui界面制作及打包成exe的操作方法(二)
Oct 12 #Python
使用Python将xmind脑图转成excel用例的实现代码(一)
Oct 12 #Python
使用python把xmind转换成excel测试用例的实现代码
Oct 12 #Python
Python Sqlalchemy如何实现select for update
Oct 12 #Python
浅析PyCharm 的初始设置(知道)
Oct 12 #Python
Pandas替换及部分替换(replace)实现流程详解
Oct 12 #Python
Django windows使用Apache实现部署流程解析
Oct 12 #Python
You might like
php数据库抽象层 PDO
2011/05/07 PHP
ThinkPHP与PHPExcel冲突解决方法
2011/08/08 PHP
php实现信用卡校验位算法THE LUHN MOD-10示例
2014/05/07 PHP
php制作的简单验证码识别代码
2016/01/26 PHP
js对象的构造和继承实现代码
2010/12/05 Javascript
jQuery拖拽 & 弹出层 介绍与示例
2013/12/27 Javascript
JavaScript获取短信验证码(周期性)
2016/12/29 Javascript
BootStrap Table前台和后台分页对JSON格式的要求
2017/06/28 Javascript
微信小程序 sha1 实现密码加密实例详解
2017/07/06 Javascript
vue使用技巧及vue项目中遇到的问题
2018/06/04 Javascript
浅谈Webpack下多环境配置的思路
2018/06/27 Javascript
Vue中props的详解
2019/05/16 Javascript
Echarts实现单条折线可拖拽效果
2019/12/19 Javascript
nuxt 服务器渲染动态设置 title和seo关键字的操作
2020/11/05 Javascript
Python中利用函数装饰器实现备忘功能
2015/03/30 Python
python中self原理实例分析
2015/04/30 Python
python numpy 部分排序 寻找最大的前几个数的方法
2018/06/27 Python
Django 路由系统URLconf的使用
2018/10/11 Python
Python基础教程之if判断,while循环,循环嵌套
2019/04/25 Python
PyQt5笔记之弹出窗口大全
2019/06/20 Python
Django文件存储 默认存储系统解析
2019/08/02 Python
python3.8 微信发送服务器监控报警消息代码实现
2019/11/05 Python
Python获取统计自己的qq群成员信息的方法
2019/11/15 Python
Python csv文件的读写操作实例详解
2019/11/19 Python
python 爬取马蜂窝景点翻页文字评论的实现
2020/01/20 Python
Django 用户登陆访问限制实例 @login_required
2020/05/13 Python
浅谈python opencv对图像颜色通道进行加减操作溢出
2020/06/03 Python
纯css3实现的竖形无限级导航
2014/12/10 HTML / CSS
为您的家、后院、车库等在线购物:Spreetail
2019/06/17 全球购物
Looking4Parking美国:全球排名第一的机场停车比较品牌
2019/08/26 全球购物
总经理工作职责范文
2014/03/14 职场文书
中学生学雷锋演讲稿
2014/04/26 职场文书
物业总经理助理岗位职责
2014/06/29 职场文书
通信工程求职信
2014/07/16 职场文书
初中教师个人总结
2015/02/10 职场文书
探究Mysql模糊查询是否区分大小写
2021/06/11 MySQL