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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。