python协程等待执行完成_当循环运行时,如何运行协同程序并等待同步函数的结果?...
同步等待異步協同程序
如果一個異步事件循環已經通過調用loop.run_forever運行,它將阻塞執行線程,直到loop.stop被調用[請參閱docs]。因此,同步等待的唯一方法是在一個專用線程上運行事件循環,在循環上調度異步函數,然后從另一個線程同步地等待它。在
為此,我按照用戶4815162342的answer編寫了自己的最小解決方案。我還添加了在所有工作完成后清理循環的部分[參見^{}]。在
下面代碼中的main函數在一個專用線程上運行事件循環,調度事件循環上的多個任務,以及同步等待結果的任務。同步等待將阻塞,直到所需的結果準備就緒。最后,循環被關閉,并優雅地與其線程一起清理。在
專用線程和函數stop_loop、run_forever_safe、和{}可以封裝在模塊或類中。在
有關線程安全的注意事項,請參閱asyncio docs中的“Concurrency and Multithreading”部分。在import asyncio
import threading
#
def stop_loop(loop):
''' stops an event loop '''
loop.stop()
print (".: LOOP STOPPED:", loop.is_running())
def run_forever_safe(loop):
''' run a loop for ever and clean up after being stopped '''
loop.run_forever()
# NOTE: loop.run_forever returns after calling loop.stop
# cancell all tasks and close the loop gracefully
print(".: CLOSING LOOP...")
# source:
loop_tasks_all = asyncio.Task.all_tasks(loop=loop)
for task in loop_tasks_all: task.cancel()
# NOTE: `cancel` does not guarantee that the Task will be cancelled
for task in loop_tasks_all:
if not (task.done() or task.cancelled()):
try:
# wait for task cancellations
loop.run_until_complete(task)
except asyncio.CancelledError: pass
#END for
print(".: ALL TASKS CANCELLED.")
loop.close()
print(".: LOOP CLOSED:", loop.is_closed())
def await_sync(task):
''' synchronously waits for a task '''
while not task.done(): pass
print(".: AWAITED TASK DONE")
return task.result()
#
async def asyncTask(loop, k):
''' asynchronous task '''
print(" start async task %s" % k)
await asyncio.sleep(3, loop=loop)
print(" end async task %s." % k)
key = "KEY#%s" % k
return key
def main():
loop = asyncio.new_event_loop() # construct a new event loop
# closures for running and stopping the event-loop
run_loop_forever = lambda: run_forever_safe(loop)
close_loop_safe = lambda: loop.call_soon_threadsafe(stop_loop, loop)
# make dedicated thread for running the event loop
thread = threading.Thread(target=run_loop_forever)
# add some tasks along with my particular task
myTask = asyncio.run_coroutine_threadsafe(asyncTask(loop, 100200300), loop=loop)
otherTasks = [asyncio.run_coroutine_threadsafe(asyncTask(loop, i), loop=loop)
for i in range(1, 10)]
# begin the thread to run the event-loop
print(".: EVENT-LOOP THREAD START")
thread.start()
# _synchronously_ wait for the result of my task
result = await_sync(myTask) # blocks until task is done
print("* final result of my task:", result)
#... do lots of work ...
print("*** ALL WORK DONE ***")
#========================================
# close the loop gracefully when everything is finished
close_loop_safe()
thread.join()
#
main()
總結
以上是生活随笔為你收集整理的python协程等待执行完成_当循环运行时,如何运行协同程序并等待同步函数的结果?...的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: oracle默认导出路径linux,传统
- 下一篇: python如何提高程序可读性_提高Py
