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中的yield浅析
Jun 16 Python
Python实现的检测网站挂马程序
Nov 30 Python
浅谈Python的Django框架中的缓存控制
Jul 24 Python
python 划分数据集为训练集和测试集的方法
Dec 11 Python
BP神经网络原理及Python实现代码
Dec 18 Python
对dataframe数据之间求补集的实例详解
Jan 30 Python
django 使用 PIL 压缩图片的例子
Aug 16 Python
基于Python实现剪切板实时监控方法解析
Sep 11 Python
Python的缺点和劣势分析
Nov 19 Python
浅谈pytorch、cuda、python的版本对齐问题
Jan 15 Python
Python通过字典映射函数实现switch
Nov 06 Python
python实现Nao机器人的单目测距
Sep 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
地球防卫队:陪着奥特曼打小怪兽的人类力量 那些经典队服
2020/03/08 日漫
用phpmyadmin更改mysql5.0登录密码
2008/03/25 PHP
ThinkPHP使用Ueditor的方法详解
2016/05/20 PHP
php使用高斯算法实现图片的模糊处理功能示例
2016/11/11 PHP
简单谈谈PHP面向对象之标识对象
2017/06/27 PHP
用jquery实现下拉菜单效果的代码
2010/07/25 Javascript
javascript中数组的冒泡排序使用示例
2013/12/18 Javascript
css+js实现部分区域高亮可编辑遮罩层
2014/03/04 Javascript
简单谈谈JavaScript的同步与异步
2015/12/31 Javascript
Angular2从搭建环境到开发步骤详解
2016/10/17 Javascript
想学习javascript JS和jQuery哪个重要 先学哪个
2016/12/11 Javascript
js从输入框读取内容,比较两个数字的大小方法
2017/03/13 Javascript
js实现多张图片延迟加载效果
2017/07/17 Javascript
vue 组件中slot插口的具体用法
2018/04/03 Javascript
vue实现重置表单信息为空的方法
2018/09/29 Javascript
AngularJs返回前一页面时刷新一次前面页面的方法
2018/10/09 Javascript
vue最简单的前后端交互示例详解
2018/10/11 Javascript
vue组件传值的实现方式小结【三种方式】
2020/02/05 Javascript
Python批处理更改文件名os.rename的方法
2018/10/26 Python
python使用matplotlib绘制热图
2018/11/07 Python
Python3之不使用第三方变量,实现交换两个变量的值
2019/06/26 Python
使用django实现一个代码发布系统
2019/07/18 Python
用CSS3来实现社交分享按钮
2014/11/11 HTML / CSS
CSS3中box-shadow的用法介绍
2015/07/15 HTML / CSS
html5关于外链嵌入页面通信问题(postMessage解决跨域通信)
2020/07/20 HTML / CSS
Maison Lab荷兰:名牌Outlet购物
2018/08/10 全球购物
全球最大的瓷器、水晶和银器零售商:Replacements
2020/06/15 全球购物
应届大专毕业生个人自荐信
2013/09/22 职场文书
优秀中学生事迹材料
2014/01/31 职场文书
能源工程专业应届生求职信
2014/03/01 职场文书
经典而简洁的婚礼主持词
2014/03/13 职场文书
文科毕业生自荐书范文
2014/04/17 职场文书
英语自我介绍演讲稿
2014/09/01 职场文书
初中生散播谣言检讨书
2014/11/17 职场文书
2014年会计个人工作总结
2014/11/24 职场文书
《检阅》教学反思
2016/02/22 职场文书