Django如何使用asyncio协程和ThreadPoolExecutor多线程

 更新时间:2020年10月12日 10:53:58   作者:傻白甜++  
这篇文章主要介绍了Django如何使用asyncio协程和ThreadPoolExecutor多线程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

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 nose单元测试框架的安装与使用

    详解Python nose单元测试框架的安装与使用

    本篇文章主要介绍了详解Python nose单元测试框架的安装与使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • Python变量命名规范的总结

    Python变量命名规范的总结

    在Python编程中,变量命名规范对于编写优雅和可维护的代码至关重要,本文主要介绍了Python变量命名规范的总结,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • 使用Python爬虫框架获取HTML网页中指定区域的数据

    使用Python爬虫框架获取HTML网页中指定区域的数据

    在当今互联网时代,数据已经成为了一种宝贵的资源,无论是进行市场分析、舆情监控,还是进行学术研究,获取网页中的数据都是一个非常重要的步骤,Python提供了多种爬虫框架来帮助我们高效地获取网页数据,本文将详细介绍如何使用Python爬虫框架来获取HTML网页中指定区域的数据
    2025-03-03
  • 详解python播放音频的三种方法

    详解python播放音频的三种方法

    这篇文章主要介绍了python播放音频的三种方法,每种方法通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • 弄清Pytorch显存的分配机制

    弄清Pytorch显存的分配机制

    这篇文章主要介绍了Pytorch显存的分配机制的相关资料,帮助大家更好的理解和使用Pytorch,感兴趣的朋友可以了解下
    2020-12-12
  • Python中的下划线详解

    Python中的下划线详解

    这篇文章主要介绍了Python中的下划线详解,本文讲解了单个下划线直接做变量名、单下划线前缀的名称、双下划线前缀的名称等内容,需要的朋友可以参考下
    2015-06-06
  • Python ORM框架SQLAlchemy学习笔记之安装和简单查询实例

    Python ORM框架SQLAlchemy学习笔记之安装和简单查询实例

    这篇文章主要介绍了Python ORM框架SQLAlchemy学习笔记之安装和简单查询实例,简明入门教程,需要的朋友可以参考下
    2014-06-06
  • 详解Python中__str__和__repr__方法的区别

    详解Python中__str__和__repr__方法的区别

    这篇文章主要介绍了__str__和__repr__方法的区别 ,__str__和__repr__是基本的内置方法,使用时的区别也是Python学习当中的基础,需要的朋友可以参考下
    2015-04-04
  • 基于PyQt5制作一个动态指针时钟

    基于PyQt5制作一个动态指针时钟

    这篇文章主要和大家分享如何利用Python中的PyQt5制作一个动态指针时钟来显示实时时间,文中的示例代码讲解详细,需要的可以参考一下
    2022-02-02
  • python动画manim中的颜色ManimColor的使用方法详解

    python动画manim中的颜色ManimColor的使用方法详解

    这篇文章主要介绍了python动画manim中的颜色ManimColor的使用方法,本文通过实例图文展示给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-08-08

最新评论