停止asyncio.run()忽略我的代码其余部分

时间:2019-06-08 00:08:33

标签: python python-asyncio

只要同步代码继续运行,我打算运行一个异步函数(该函数与程序的其他部分有关,但什么也不返回)。不过,在我运行asyncio.run()命令之后,该程序只会永远执行异步命令。

我尝试了一些基本的线程和多进程Pool方法,但是我发现这是我尝试过的最成功的方法:

# There's some code up here (A), and it runs synchronously and fine.

# Here's the asynchronous code (B).
pauseAsynchronousFunction = False

async def asynchronousFunction():
    global pauseAsynchronousFunction
    # Do stuff before hitting the while loop.
    while True:
        if pauseAsynchronousFunction == False:
            # Do some stuff.
        else:
            # Do some other stuff.

asyncio.run(pauseAsynchronousFunction())

# More synchronous code is down here (C), which it never reaches.

我可以说它没有按预期运行,因为(C中的)另一个函数调用相同的全局变量pauseAsynchronousFunction并将其从False切换到True,然后返回False再次运行完毕。这种切换永远不会发生。

我猜测问题可能与while True有关,我不明白为什么它是异步的,或者与不包含await语句有关。我还可能缺少什么?

更新:

在pypypy的帮助下,我进行了几次调试尝试,并得到了它。


pauseAsynchronousFunction = False

async def fun2():
    global pauseAsynchronousFunction
    while True:
        if pauseAsynchronousFunction == False:
            #do stuff
        else:
            #do other stuff

async def fun1():
    global pauseAsynchronousFunction
    pauseAsynchronousFunction = True
    #do stuff here that you wanted to do after the `asyncio.run` above
    pauseAsynchronousFunction = False
    return stuff

async def main():
    await asyncio.gather(
        fun1(),
        fun2(),
    )

asyncio.run(main)

问题似乎是这样的: pauseAsynchronousFunction切换到True,但不会在False的末尾切换回到fun(1)

1 个答案:

答案 0 :(得分:1)

asyncio.run将阻塞,直到您的异步函数全部返回为止。因此,asyncio.run()之后的代码应转换为异步函数,即

import asyncio

async def fun2():
    global pauseAsynchronousFunction
    while True:
        if pauseAsynchronousFunction == False:
            print('not paused')
        else:
            print('paused')
        await asyncio.sleep(1)

async def fun1():
    global pauseAsynchronousFunction
    pauseAsynchronousFunction = True
    print('im pausing')
    await asyncio.sleep(5)
    print('im unpausing')
    pauseAsynchronousFunction = False
    return 0

async def main():
    await asyncio.gather(
        fun1(),
        fun2(),
    )

await main()

这是使用线程和事件的另一种答案:

import threading
import time

should_pause = threading.Event()

def fun2():
    while True:
        if should_pause.is_set():
            print('paused')
        else:
            print('not paused')
        time.sleep(1)


t = threading.Thread(target=fun2)
t.start()
should_pause.set()
print('waiting')
time.sleep(5)
print('finished-waiting')
should_pause.clear()