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爬虫之爬虫框架Scrapy安装配置
Nov 06 Python
Python和perl实现批量对目录下电子书文件重命名的代码分享
Nov 21 Python
python中while循环语句用法简单实例
May 07 Python
Python中使用ElementTree解析XML示例
Jun 02 Python
python嵌套字典比较值与取值的实现示例
Nov 03 Python
详解Django解决ajax跨域访问问题
Aug 24 Python
Python中文件的写入读取以及附加文字方法
Jan 23 Python
python+pyqt5实现图片批量缩放工具
Mar 18 Python
python tkinter窗口最大化的实现
Jul 15 Python
python梯度下降算法的实现
Feb 24 Python
python 实现表情识别
Nov 21 Python
基于Python采集爬取微信公众号历史数据
Nov 27 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
hadoop中一些常用的命令介绍
2013/06/19 PHP
php错误日志简单配置方法
2016/07/11 PHP
PHP给前端返回一个JSON对象的实例讲解
2018/05/31 PHP
Mac下快速搭建PHP开发环境步骤详解
2019/05/05 PHP
判断页面是关闭还是刷新的js代码
2007/01/28 Javascript
IE8 引入跨站数据获取功能说明
2008/07/22 Javascript
Javascript实现滑块滑动改变值的实现代码
2013/04/12 Javascript
浅析Bootstrap缩略图组件与警示框组件
2016/04/29 Javascript
vue分页组件table-pagebar使用实例解析
2020/11/15 Javascript
原生JS实现图片轮播与淡入效果的简单实例
2016/08/21 Javascript
Node.js下自定义错误类型详解
2016/10/17 Javascript
微信小程序  audio音频播放详解及实例
2016/11/02 Javascript
一个例子轻松学会Vue.js
2017/01/02 Javascript
JavaScript装饰器函数(Decorator)实例详解
2017/03/30 Javascript
React Js 微信禁止复制链接分享禁止隐藏右上角菜单功能
2017/05/26 Javascript
关于Vue背景图打包之后访问路径错误问题的解决
2017/11/03 Javascript
JavaScript中var的重要性实例分析
2019/07/09 Javascript
vue-router结合vuex实现用户权限控制功能
2019/11/14 Javascript
Angular8 简单表单验证的实现示例
2020/06/03 Javascript
JS数组reduce()方法原理及使用技巧解析
2020/07/14 Javascript
[39:32]2014 DOTA2国际邀请赛中国区预选赛 TongFu VS DT 第二场
2014/05/23 DOTA
Python调用服务接口的实例
2019/01/03 Python
对python中if语句的真假判断实例详解
2019/02/18 Python
python实现AES加密和解密
2019/03/27 Python
python调用pyaudio使用麦克风录制wav声音文件的教程
2019/06/26 Python
Anaconda 查看、创建、管理和使用python环境的方法
2019/12/03 Python
Python3.9又更新了:dict内置新功能
2020/02/28 Python
可打印的优惠券、杂货和优惠券代码:Coupons.com
2018/06/12 全球购物
世嘉游戏英国官方商店:SEGA Shop UK
2019/09/20 全球购物
几个常见的消息中间件(MOM)
2014/01/08 面试题
Java面试题:Java类的Main方法如果是Private将会怎么样
2016/08/18 面试题
电子信息专业自荐书
2014/02/04 职场文书
公司合作协议范文
2014/10/01 职场文书
2014年管理人员工作总结
2014/12/01 职场文书
医学生自荐信范文
2015/03/05 职场文书
如何用python反转图片,视频
2021/04/24 Python