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 인스턴스 코드를 사용하면 다음과 같습니다(입출력 작업이 여러 개 있을 때).

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 인스턴스 코드를 사용하면 다음과 같습니다(입출력 작업이 여러 개 있을 경우).

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
이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.

좋은 웹페이지 즐겨찾기