Django如何使用asyncio协程和ThreadPoolExecutor多线程
Django视图函数执行,不在主线程中,直接loop=asyncio.new_event_loop()
#不能loop=asyncio.get_event_loop()会触发RuntimeError:Thereisnocurrenteventloopinthread
因为asyncio程序中的每个线程都有自己的事件循环,但它只会在主线程中为你自动创建一个事件循环。所以如果你asyncio.get_event_loop在主线程中调用一次,它将自动创建一个循环对象并将其设置为默认值,但是如果你在一个子线程中再次调用它,你会得到这个错误。相反,您需要在线程启动时显式创建/设置事件循环:
loop=asyncio.new_event_loop()
asyncio.set_event_loop(loop)
在Django单个视图中使用asyncio实例代码如下(有多个IO任务时)
fromdjango.viewsimportView importasyncio importtime fromdjango.httpimportJsonResponse classTestAsyncioView(View): defget(self,request,*args,**kwargs): """ 利用asyncio和asyncawait关键字(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() returnJsonResponse({'results':results,'cost_time':(end_time-start_time)}) asyncdefgather_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=awaitasyncio.gather(*tasks) returnresults asyncdefmake_future(self,func,*args): future=self.loop.run_in_executor(None,func,*args) response=awaitfuture returnresponse defio_task1(self,sleep_time): time.sleep(sleep_time) return66 defio_task2(self,sleep_time): time.sleep(sleep_time) return77 asyncdefio_task3(self,sleep_time): #awaitasyncio.sleep(sleep_time) s=awaitself.do(sleep_time) returns asyncdefdo(self,sleep_time): awaitasyncio.sleep(sleep_time) return66
在Django单个视图中使用ThreadPoolExecutor实例代码如下(有多个IO任务时)
fromdjango.viewsimportView importtime fromconcurrent.futuresimportThreadPoolExecutor,as_completed classTestThreadView(View): defget(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) withThreadPoolExecutor(len(tasks))asexecutor: fortaskintasks: future=executor.submit(task,5) future_set.add(future) forfutureinas_completed(future_set): error=future.exception() iferrorisnotNone: raiseerror results=self.get_results(future_set) end_time=time.time() returnJsonResponse({'results':results,'cost_time':(end_time-start_time)}) defget_results(self,future_set): results=[] forfutureinfuture_set: results.append(future.result()) returnresults defio_task1(self,sleep_time): time.sleep(sleep_time) return66 defio_task2(self,sleep_time): time.sleep(sleep_time) return77
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。