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 相关文章推荐
pymssql ntext字段调用问题解决方法
Dec 17 Python
Python 调用DLL操作抄表机
Jan 12 Python
用pywin32实现windows模拟鼠标及键盘动作
Apr 22 Python
Python中运行并行任务技巧
Feb 26 Python
win7上python2.7连接mysql数据库的方法
Jan 14 Python
Python 基础教程之包和类的用法
Feb 23 Python
python实现zabbix发送短信脚本
Sep 17 Python
python去掉 unicode 字符串前面的u方法
Oct 21 Python
pyhanlp安装介绍和简单应用
Feb 22 Python
Pytorch 抽取vgg各层并进行定制化处理的方法
Aug 20 Python
Python Request类源码实现方法及原理解析
Aug 17 Python
pip/anaconda修改镜像源,加快python模块安装速度的操作
Mar 04 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将图片保存入mysql数据库失败的解决方法
2014/12/27 PHP
四种php中webservice实现的简单架构方法及实例
2015/02/03 PHP
PHP入门教程之表单与验证实例详解
2016/09/11 PHP
ThinkPHP框架实现的邮箱激活功能示例
2018/06/15 PHP
前端开发必须知道的JS之原型和继承
2010/07/06 Javascript
multiSteps 基于Jquery的多步骤滑动切换插件
2011/07/22 Javascript
原生js写的放大镜效果
2012/08/22 Javascript
Jquery如何实现点击时高亮显示代码
2014/01/22 Javascript
jquery实现网页查找功能示例分享
2014/02/12 Javascript
Bootstrap学习笔记之css样式设计(1)
2016/06/07 Javascript
Angular 应用技巧总结
2016/09/14 Javascript
JQuery实现DIV其他动画效果的简单实例
2016/09/18 Javascript
JS操作时间 - UNIX时间戳的简单介绍(必看篇)
2017/08/16 Javascript
利用Javascript获取选择文本所在的句子详解
2017/12/03 Javascript
layui radio性别单选框赋值方法
2018/08/15 Javascript
发布一款npm包帮助理解npm的使用
2019/01/03 Javascript
Vue+ElementUI项目使用webpack输出MPA的方法
2019/08/27 Javascript
python实现汉诺塔方法汇总
2016/07/25 Python
python爬虫之BeautifulSoup 使用select方法详解
2017/10/23 Python
Python内置函数 next的具体使用方法
2017/11/24 Python
Python 字符串与二进制串的相互转换示例
2018/07/23 Python
Python判断两个文件是否相同与两个文本进行相同项筛选的方法
2019/03/01 Python
python pyqtgraph 保存图片到本地的实例
2020/03/14 Python
Django Form常用功能及代码示例
2020/10/13 Python
matplotlib事件处理基础(事件绑定、事件属性)
2021/02/03 Python
海淘零差价,宝贝全球购: 宝贝格子
2016/08/24 全球购物
国外最大的眼镜网站:Coastal
2017/08/09 全球购物
怀旧收藏品和经典纪念品:Betty’s Attic
2018/08/29 全球购物
商务日语毕业生自荐信范文
2013/11/14 职场文书
保安部任务及岗位职责
2014/02/25 职场文书
2014年食品安全工作总结
2014/12/04 职场文书
五好文明家庭事迹材料
2014/12/20 职场文书
2015年节能减排工作总结
2015/05/14 职场文书
如何制定一份可行的计划!
2019/06/21 职场文书
vue使用Google Recaptcha验证的实现示例
2021/08/23 Vue.js
【海涛教你打DOTA】死灵飞龙第一视角解说
2022/04/01 DOTA