标签:协程 self 视图 future io time 多线程 loop asyncio
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
标签:协程,self,视图,future,io,time,多线程,loop,asyncio 来源: https://www.cnblogs.com/feifeifeisir/p/13723054.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。