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实现合并字典的方法
Jul 07 Python
python版学生管理系统
Jan 10 Python
Python二进制串转换为通用字符串的方法
Jul 23 Python
Python中应该使用%还是format来格式化字符串
Sep 25 Python
python爬虫之快速对js内容进行破解
Jul 09 Python
python multiprocessing模块用法及原理介绍
Aug 20 Python
Django中自定义模型管理器(Manager)及方法
Sep 23 Python
Python使用matplotlib绘制Logistic曲线操作示例
Nov 28 Python
python进程的状态、创建及使用方法详解
Dec 06 Python
Python读写操作csv和excle文件代码实例
Mar 16 Python
python操作yaml说明
Apr 08 Python
python 数据类型强制转换的总结
Jan 25 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-cgi.exe - FastCGI 进程超过了配置的请求超时时限)的问题
2013/07/03 PHP
php json_encode()函数返回json数据实例代码
2014/10/10 PHP
thinkphp配置连接数据库技巧
2014/12/02 PHP
javascript背投广告代码的完善
2008/04/08 Javascript
JavaScript字符串String和Array操作的有趣方法
2012/12/18 Javascript
js中判断变量类型函数typeof的用法总结
2016/08/09 Javascript
自动化测试读写64位操作系统的注册表
2016/08/15 Javascript
Vue.js每天必学之Class与样式绑定
2016/09/05 Javascript
webpack常用配置项配置文件介绍
2016/11/07 Javascript
Web纯前端“旭日图”实现元素周期表
2017/03/10 Javascript
微信小程序数据统计和错误统计的实现方法
2019/06/26 Javascript
JavaScript中Dom操作实例详解
2019/07/08 Javascript
JavaScript基础之this和箭头函数详析
2019/09/05 Javascript
javascript实现动态时钟的启动和停止
2020/07/29 Javascript
[07:54]DOTA2-DPC中国联赛 正赛 iG vs VG 选手采访
2021/03/11 DOTA
详解Python中的文本处理
2015/04/11 Python
python创建一个最简单http webserver服务器的方法
2015/05/08 Python
python 根据正则表达式提取指定的内容实例详解
2016/12/04 Python
Python3中简单的文件操作及两个简单小实例分享
2017/06/18 Python
Python实现两款计算器功能示例
2017/12/19 Python
django如何实现视图重定向
2019/07/24 Python
Python3安装pip工具的详细步骤
2019/10/14 Python
python实现引用其他路径包里面的模块
2020/03/09 Python
python如何调用字典的key
2020/05/25 Python
详解numpy.ndarray.reshape()函数的参数问题
2020/10/13 Python
python抢购软件/插件/脚本附完整源码
2021/03/04 Python
Html5 new XMLHttpRequest()监听附件上传进度
2021/01/14 HTML / CSS
美国摄影爱好者购物网站:Focus Camera
2016/10/21 全球购物
Perfume’s Club法国站:购买香水和化妆品
2019/05/02 全球购物
生产经理的自我评价分享
2013/11/07 职场文书
教育专业个人求职信
2013/12/02 职场文书
大学生学习自我评价
2014/01/13 职场文书
《大自然的语言》教学反思
2014/04/08 职场文书
幼儿园大班开学寄语(2016秋季)
2015/12/03 职场文书
解决golang post文件时Content-Type出现的问题
2021/05/02 Golang
Python机器学习之KNN近邻算法
2021/05/14 Python