1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > python协程等待执行完成_当循环运行时 如何运行协同程序并等待同步函数的结果?...

python协程等待执行完成_当循环运行时 如何运行协同程序并等待同步函数的结果?...

时间:2018-08-13 12:44:12

相关推荐

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, 10000), 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()

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。