网络编程
位置:首页>> 网络编程>> Python编程>> Django如何使用asyncio协程和ThreadPoolExecutor多线程

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

作者:傻白甜++  发布时间:2022-06-22 11:43:34 

标签: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

来源:https://www.cnblogs.com/feifeifeisir/p/13723054.html

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com