Python asyncio 简单示例

标签 python multiprocessing python-asyncio python-3.5 event-driven

我正在尝试使用 python 的 asyncio 协议(protocol)。我发现this example来自官方文档并希望对其进行稍微修改并重现其行为。所以我写了以下两个脚本:

# file: get_rand.py
from random import choice
from time import sleep

def main():
    print(choice('abcdefghijklmnopqrstuvwxyz'))
    sleep(2)

if __name__ == '__main__':
    main()

和:

# file: async_test.py
import asyncio

class Protocol(asyncio.SubprocessProtocol):

    def __init__(self, exit_future):
        self.exit_future = exit_future
        self.output = bytearray()
        print('Protocol initialised')

    def pipe_data_received(self, fd, data):
        print('Data received')
        self.output.extend(data)

    #def pipe_connection_lost(self, fd, exc):
    #    print('Pipe connection lost for the following reason:')
    #    print(exc)

    def subprocess_exited(self):
        print('Subprocess exited')
        self.exit_future.set_result(True)


@asyncio.coroutine
def get_rand(loop):
    exit_future = asyncio.Future(loop=loop)
    print('Process created')
    created = loop.subprocess_exec(lambda: Protocol(exit_future),
                                   'python3.5', 'get_rand.py',
                                   stdin=None, stderr=None)
    print('Getting pipes...')
    transport, protocol = yield from created
    print('Waiting for child to exit...')
    yield from exit_future
    transport.close()
    print('Gathering data...')
    data = bytes(protocol.output)
    print('Returning data...')
    return data.decode('ascii').rstrip()

def main():
    loop = asyncio.get_event_loop()
    print('Event loop started')
    data = loop.run_until_complete(get_rand(loop))
    print('Event loop ended')
    print(data)
    loop.close()

if __name__ == '__main__':
    main()

当我运行 async_test.py 时,我得到以下输出:

$ python3.5 async_test.py 
Event loop started
Process created
Getting pipes...
Protocol initialised
Waiting for child to exit...
Data received

它只是挂起。

如果我取消注释 pipe_connection_lost 方法,输出如下:

$ python3.5 async_test.py 
Event loop started
Process created
Getting pipes...
Protocol initialised
Waiting for child to exit...
Data received
Pipe connection lost for the following reason:
None

进程仍然挂起。我认为正在发生的情况是,由于某种原因,子进程 (get_rand.py) 关闭了管道(如上面的输出所示),但没有终止,以便父进程可以从 解除阻止从 exit_future 中产生。考虑到我的代码主要是从 python 文档中的示例复制粘贴的,我真的不明白这种行为背后的原因。

最佳答案

更改def subprocess_exited(self):

def process_exited(self):

关于Python asyncio 简单示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34882079/

相关文章:

python-3.x - 协程的 Python 3.8 模拟

python - 从 NBA API 收集特定球员信息

python - 在 python 中使用多处理来加速 IO

python - 使用二级索引复制 DataFrame 中的 n 行?

python - python manager dict 会自动锁定它的值吗?

python - 使用多处理运行子进程时出现系统错误

Python 从同步函数运行非阻塞异步函数

python - 子进程在终止前获取结果

Python 正则表达式删除空格 b/w 括号和数字

python - 命名组内的非捕获组