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获取当前计算机cpu数量的方法
Apr 18 Python
python实现自动登录人人网并采集信息的方法
Jun 28 Python
win10下Python3.6安装、配置以及pip安装包教程
Oct 01 Python
Python3连接SQLServer、Oracle、MySql的方法
Jun 28 Python
flask中过滤器的使用详解
Aug 01 Python
Python 数值区间处理_对interval 库的快速入门详解
Nov 16 Python
Django框架验证码用法实例分析
May 10 Python
Python3.5以上版本lxml导入etree报错的解决方案
Jun 26 Python
python科学计算之numpy——ufunc函数用法
Nov 25 Python
python GUI模拟实现计算器
Jun 22 Python
浅谈django框架集成swagger以及自定义参数问题
Jul 07 Python
python 密码学示例——凯撒密码的实现
Sep 21 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
fleaphp下不确定的多条件查询的巧妙解决方法
2008/09/11 PHP
php pdo oracle中文乱码的快速解决方法
2016/05/16 PHP
PHP学习笔记之php文件操作
2016/06/03 PHP
javascript实现动态增加删除表格行(兼容IE/FF)
2007/04/02 Javascript
33种Javascript 表格排序控件收集
2009/12/03 Javascript
ExtJS Ext.MessageBox.alert()弹出对话框详解
2010/04/02 Javascript
基于jquery的内容循环滚动小模块(仿新浪微博未登录首页滚动微博显示)
2011/03/28 Javascript
解析offsetHeight,clientHeight,scrollHeight之间的区别
2013/11/20 Javascript
js验证身份证号有效性并提示对应信息
2015/10/19 Javascript
jQuery中队列queue()函数的实例教程
2016/05/03 Javascript
JavaScript Promise 用法
2016/06/14 Javascript
关于JS中的方法是否加括号的问题
2016/07/27 Javascript
原生javascript实现读写CSS样式的方法详解
2017/02/20 Javascript
angular中的cookie读写方法
2017/08/02 Javascript
vue.js根据代码运行环境选择baseurl的方法
2018/02/28 Javascript
快速解决select2在bootstrap模态框中下拉框隐藏的问题
2018/08/10 Javascript
ES6 Generator基本使用方法示例
2020/06/06 Javascript
在Python的Django框架中编写编译函数
2015/07/20 Python
python xlsxwriter创建excel图表的方法
2018/06/11 Python
Python实现的合并两个有序数组算法示例
2019/03/04 Python
python multiprocessing模块用法及原理介绍
2019/08/20 Python
python 3.7.4 安装 opencv的教程
2019/10/10 Python
解决Pycharm 导入其他文件夹源码的2种方法
2020/02/12 Python
TensorFlow tf.nn.softmax_cross_entropy_with_logits的用法
2020/04/19 Python
Numpy中np.random.rand()和np.random.randn() 用法和区别详解
2020/10/23 Python
python绘图模块之利用turtle画图
2021/02/12 Python
国际礼品店:GiftsnIdeas
2018/05/03 全球购物
J2EE系统只能是基于web
2015/09/08 面试题
机电工程学生自荐信范文
2013/12/07 职场文书
教师个人的自我评价分享
2014/01/02 职场文书
餐厅销售主管职责范本
2014/02/19 职场文书
小学综合实践活动总结
2014/07/07 职场文书
学校工作推荐信范文
2014/07/11 职场文书
李清照的诗词赏析(20首)
2019/08/22 职场文书
MySQL系列之十 MySQL事务隔离实现并发控制
2021/07/02 MySQL
Nginx 路由转发和反向代理location配置实现
2021/11/11 Servers