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 相关文章推荐
windows下安装python paramiko模块的代码
Feb 10 Python
用Python的Flask框架结合MySQL写一个内存监控程序
Nov 07 Python
python类的继承实例详解
Mar 30 Python
python中解析json格式文件的方法示例
May 03 Python
解决出现Incorrect integer value: '' for column 'id' at row 1的问题
Oct 29 Python
在pycharm中设置显示行数的方法
Jan 16 Python
Python里字典的基本用法(包括嵌套字典)
Feb 27 Python
Python os模块常用方法和属性总结
Feb 20 Python
python 6.7 编写printTable()函数表格打印(完整代码)
Mar 25 Python
解决Django Haystack全文检索为空的问题
May 19 Python
Python 通过爬虫实现GitHub网页的模拟登录的示例代码
Aug 17 Python
Python3使用Selenium获取session和token方法详解
Feb 16 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数组编码gbk与utf8互相转换的两种方法
2016/09/01 PHP
PHP单例模式与工厂模式详解
2017/08/29 PHP
javascript中的继承实例代码
2011/04/27 Javascript
jquery自定义属性(类型/属性值)
2013/05/21 Javascript
Node.js中使用Log.io在浏览器中实时监控日志(等同tail -f命令)
2014/09/17 Javascript
js获取时间并实现字符串和时间戳之间的转换
2015/01/05 Javascript
简介JavaScript中的push()方法的使用
2015/06/09 Javascript
javascript比较两个日期相差天数的方法
2015/07/24 Javascript
jquery实现网页的页面平滑滚动效果代码
2015/11/02 Javascript
如何解决ligerUI布局时Center中的Tab高度大小
2015/11/24 Javascript
JavaScript和jquery获取父级元素、子级元素、兄弟元素的方法
2016/06/05 Javascript
深入浅析JS是按值传递还是按引用传递(推荐)
2016/09/18 Javascript
nodejs结合Socket.IO实现的即时通讯功能详解
2018/01/12 NodeJs
Bootstrap Fileinput 4.4.7文件上传实例详解
2018/07/25 Javascript
JS温故而知新之变量提升和时间死区
2019/01/27 Javascript
JavaScript遍历查找数组中最大值与最小值的方法示例
2019/05/24 Javascript
微信小程序实现下拉刷新动画
2019/06/21 Javascript
[15:28]DOTA2 HEROS教学视频教你分分钟做大人-剧毒术士
2014/06/13 DOTA
将Python的Django框架与认证系统整合的方法
2015/07/24 Python
Python中绑定与未绑定的类方法用法分析
2016/04/29 Python
Python爬取网页中的图片(搜狗图片)详解
2017/03/23 Python
python实现逻辑回归的方法示例
2017/05/02 Python
idea创建springMVC框架和配置小文件的教程图解
2018/09/18 Python
Window环境下Scrapy开发环境搭建
2018/11/18 Python
Python开发网站目录扫描器的实现
2019/02/21 Python
python实现的config文件读写功能示例
2019/09/24 Python
Python利用FFT进行简单滤波的实现
2020/02/26 Python
pandas使用函数批量处理数据(map、apply、applymap)
2020/11/27 Python
使用html5+css3来实现slider切换效果告别javascript+css
2013/01/08 HTML / CSS
什么情况下你必须要把一个类定义为abstract的
2013/01/06 面试题
教师队伍管理制度
2014/01/14 职场文书
旅游饭店管理专业自荐书
2014/06/28 职场文书
四风之害观后感
2015/06/09 职场文书
2015年治庸问责工作总结
2015/07/27 职场文书
2016年春季运动会广播稿
2015/08/19 职场文书
创业计划书之DIY自助厨房
2019/09/06 职场文书