Django如何使用asyncio協(xié)程和ThreadPoolExecutor多線程
Django視圖函數(shù)執(zhí)行,不在主線程中,直接loop = asyncio.new_event_loop()
# 不能loop = asyncio.get_event_loop() 會觸發(fā)RuntimeError: There is no current event loop in thread
因為asyncio程序中的每個線程都有自己的事件循環(huán),但它只會在主線程中為你自動創(chuàng)建一個事件循環(huán)。所以如果你asyncio.get_event_loop在主線程中調(diào)用一次,它將自動創(chuàng)建一個循環(huán)對象并將其設(shè)置為默認值,但是如果你在一個子線程中再次調(diào)用它,你會得到這個錯誤。相反,您需要在線程啟動時顯式創(chuàng)建/設(shè)置事件循環(huán):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
在Django單個視圖中使用asyncio實例代碼如下(有多個IO任務(wù)時)
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關(guān)鍵字(python3.5之前使用yield)實現(xiàn)協(xié)程 """ self.id = 5 start_time = time.time() ''' # 同步執(zhí)行 # 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任務(wù)時)
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
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Python 數(shù)據(jù)庫 (sqlite3)應(yīng)用
本篇文章主要介紹了Python標準庫14 數(shù)據(jù)庫 (sqlite3),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧。2016-12-12Python參數(shù)解析器configparser簡介
configparser是python自帶的配置參數(shù)解析器,可以用于解析.config文件中的配置參數(shù),ini文件中由sections(節(jié)點)-key-value組成,這篇文章主要介紹了Python參數(shù)解析器configparser,需要的朋友可以參考下2022-12-12Python實現(xiàn)求最大公約數(shù)及判斷素數(shù)的方法
這篇文章主要介紹了Python實現(xiàn)求最大公約數(shù)及判斷素數(shù)的方法,涉及Python算數(shù)運算的相關(guān)技巧,需要的朋友可以參考下2015-05-05如何基于Python實現(xiàn)一個慶祝國慶節(jié)的小程序
這篇文章主要介紹了如何基于Python實現(xiàn)一個慶祝國慶節(jié)的小程序,增加了互動選擇祝福語、查詢信息、播放背景音樂及趣味小測驗等功能,使用tkinter增強GUI,提升用戶互動體驗,需要的朋友可以參考下2024-09-09