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实现socket客户端和服务端简单示例
Feb 24 Python
Python getopt模块处理命令行选项实例
May 13 Python
python在ubuntu中的几种安装方法(小结)
Dec 08 Python
Python实现购物车程序
Apr 16 Python
python安装模块如何通过setup.py安装(超简单)
May 05 Python
Python/ArcPy遍历指定目录中的MDB文件方法
Oct 27 Python
python实现名片管理系统项目
Apr 26 Python
Python3网络爬虫开发实战之极验滑动验证码的识别
Aug 02 Python
详解python中的生成器、迭代器、闭包、装饰器
Aug 22 Python
如何基于Python Matplotlib实现网格动画
Jul 20 Python
pytorch 预训练模型读取修改相关参数的填坑问题
Jun 05 Python
Python上下文管理器Content Manager
Jun 26 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备份数据库生成SQL文件并下载的函数代码
2012/02/05 PHP
php实现用于验证所有类型的信用卡类
2015/03/24 PHP
php生成带logo二维码方法小结
2016/04/08 PHP
PHP打印输出函数汇总
2016/08/28 PHP
php通过执行CutyCapt命令实现网页截图的方法
2016/09/30 PHP
微信小程序 消息推送php服务器验证实例详解
2017/03/30 PHP
laravel框架模型中非静态方法也能静态调用的原理分析
2019/11/23 PHP
Jquery遍历节点的方法小集
2014/01/22 Javascript
当某个文本框成为焦点时即清除文本框内容
2014/04/28 Javascript
jQuery元素选择器用法实例
2014/12/23 Javascript
详解JavaScript对W3C DOM模版的支持情况
2015/06/16 Javascript
JavaScript清空数组元素的两种方法简单比较
2015/07/10 Javascript
jQuery实现时尚漂亮的弹出式对话框实例
2015/08/07 Javascript
js实现按钮颜色渐变动画效果
2015/08/20 Javascript
js中unicode转码方法详解
2015/10/09 Javascript
使用jQuery5分钟快速搞定双色表格的简单实例
2016/08/08 Javascript
Vue.js每天必学之计算属性computed与$watch
2016/09/05 Javascript
jquery attr()设置和获取属性值实例教程
2016/09/25 Javascript
利用Angular.js限制textarea输入的字数
2016/10/20 Javascript
jQuery+json实现动态创建复杂表格table的方法
2016/10/25 Javascript
用vue2.0实现点击选中active其他选项互斥的效果
2018/04/12 Javascript
如何从零开始利用js手写一个Promise库详解
2018/04/19 Javascript
es6基础学习之解构赋值
2018/12/10 Javascript
vue表单验证你真的会了吗?vue表单验证(form)validate
2019/04/07 Javascript
原生JS实现动态添加新元素、删除元素方法
2019/05/05 Javascript
vue-week-picker实现支持按周切换的日历
2019/06/26 Javascript
vue中datepicker的使用教程实例代码详解
2019/07/08 Javascript
在vue中使用echars实现上浮与下钻效果
2019/11/08 Javascript
node+multer实现图片上传的示例代码
2020/02/18 Javascript
python-视频分帧&多帧合成视频实例
2019/12/10 Python
pytorch逐元素比较tensor大小实例
2020/01/03 Python
Restful_framework视图组件代码实例解析
2020/11/17 Python
简历自荐信
2013/12/02 职场文书
创建文明城市倡议书
2015/04/28 职场文书
五年级语文教学反思
2016/03/03 职场文书
Python使用scapy模块发包收包
2021/05/07 Python