我在django视图中具有以下代码来创建后台任务:
xy
我到底需要做些什么来“杀死”循环?关闭它等的正确方法是什么?
答案 0 :(得分:2)
您无需首先开始任何事件循环。 concurrent.futures
package可以直接访问执行程序,而threading
则可以启动单个线程:
# raw thread
import threading
background_task = threading.Thread(
target=update_contacts, kwargs={
'email': email,
'access_token': g.tokens['access_token']
})
background_task.start()
# executor thread pool
from concurrent.futures import ThreadPoolExecutor
my_executor = ThreadPoolExecutor()
my_executor.submit(update_contacts, email=email, access_token=g.tokens['access_token'])
通常,如果您只想启动任务而忽略它,那么Thread
会更简单。如果您同时执行许多小任务,则ThreadPoolExecutor
会更有效率;它也可以用于自动等待多个任务的完成。
print('start at', time.time())
with ThreadPoolExecutor() as executor:
executor.submit(time.sleep, 1)
executor.submit(time.sleep, 1)
executor.submit(time.sleep, 1)
executor.submit(time.sleep, 1)
print('done at', time.time()) # triggers after all 4 sleeps have finished
loop.run_in_executor
的主要目的是 not 来提供ThreadPoolExecutor。它旨在弥合执行程序阻止代码的执行者和非阻止代码的事件循环之间的差距。没有后者,就根本不需要使用asnycio
。
import time
import asyncio
def block(delay: float):
print("Stop! Blocking Time!")
time.sleep(delay) # block the current thread
print("Done! Blocking Time!")
async def nonblock(delay: float):
print("Erm.. Non-Blocking Time!")
await asyncio.sleep(delay)
print("Done! Non-Blocking Time!")
async def multiblock(delay: float):
loop = asyncio.get_event_loop()
await asyncio.gather( # await async natively and sync via executors
nonblock(delay),
loop.run_in_executor(None, block, delay),
nonblock(delay),
loop.run_in_executor(None, block, delay),
)
asyncio.run(multiblock(1))
答案 1 :(得分:0)