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判断字符串是否纯数字的方法
Nov 19 Python
Python创建xml文件示例
Mar 22 Python
python 接口_从协议到抽象基类详解
Aug 24 Python
Python使用wxPython实现计算器
Jan 30 Python
opencv python统计及绘制直方图的方法
Jan 21 Python
python 列表输出重复值以及对应的角标方法
Jun 11 Python
Python 绘制酷炫的三维图步骤详解
Jul 12 Python
python实现输入的数据在地图上生成热力图效果
Dec 06 Python
Python3 io文本及原始流I/O工具用法详解
Mar 23 Python
树莓派升级python的具体步骤
Jul 05 Python
详解Pymongo常用查询方法总结
Jan 29 Python
2021年最新用于图像处理的Python库总结
Jun 15 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 discuz 主题表和回帖表的设计
2009/03/13 PHP
关于PHP session 存储方式的详细介绍
2013/06/25 PHP
jquery validate poshytip 自定义样式
2012/11/26 Javascript
js实现动态添加、删除行、onkeyup表格求和示例
2013/08/18 Javascript
jQuery实现异步获取json数据的2种方式
2014/08/29 Javascript
Nodejs极简入门教程(二):定时器
2014/10/25 NodeJs
Javascript控制input输入时间格式的方法
2015/01/28 Javascript
nodejs中的fiber(纤程)库详解
2015/03/24 NodeJs
JS+CSS实现分类动态选择及移动功能效果代码
2015/10/19 Javascript
详解JavaScript的表达式与运算符
2015/11/30 Javascript
jQuery将表单序列化成一个Object对象的实例
2016/11/29 Javascript
详解nodejs 文本操作模块-fs模块(一)
2016/12/22 NodeJs
详解js中常规日期格式处理、月历渲染和倒计时函数
2016/12/28 Javascript
JavaScript实现公历转农历功能示例
2017/02/13 Javascript
Ionic3 UI组件之autocomplete详解
2017/06/08 Javascript
Angular中的interceptors拦截器
2017/06/25 Javascript
JS+H5 Canvas实现时钟效果
2018/07/20 Javascript
解决vue2 在mounted函数无法获取prop中的变量问题
2018/11/15 Javascript
vue+element实现打印页面功能
2019/05/20 Javascript
通过javascript实现段落的收缩与展开
2019/06/26 Javascript
详解webpack引用jquery(第三方模块)的三种办法
2019/08/21 jQuery
layui 根据后台数据动态创建下拉框并同时默认选中的实例
2019/09/02 Javascript
让你30分钟快速掌握vue3教程
2020/10/26 Javascript
Vue开发中常见的套路和技巧总结
2020/11/24 Vue.js
[54:51]Ti4 冒泡赛第二轮LGD vs C9 3
2014/07/14 DOTA
在Django中管理Users和Permissions以及Groups的方法
2015/07/23 Python
Python数据分析之真实IP请求Pandas详解
2016/11/18 Python
selenium3+python3环境搭建教程图解
2018/12/07 Python
Python从数据库读取大量数据批量写入文件的方法
2018/12/10 Python
pybind11在Windows下的使用教程
2019/07/04 Python
获取CSDN文章内容并转换为markdown文本的python
2020/09/06 Python
如何利用python检测图片是否包含二维码
2020/10/15 Python
利用CSS3的线性渐变linear-gradient制作边框的示例
2016/06/02 HTML / CSS
详解WebSocket跨域问题解决
2018/08/06 HTML / CSS
工商局局长个人对照检查材料思想汇报
2014/09/23 职场文书
股权转让协议范本
2014/12/07 职场文书