首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么等待不等待asyncio.create_subprocess_exec()

为什么等待不等待asyncio.create_subprocess_exec()
EN

Stack Overflow用户
提问于 2018-01-23 18:37:47
回答 1查看 7.5K关注 0票数 4

在教程的基础上,我正在编写一个coroutine来执行python中的shell命令。以下是基本内容:

代码语言:javascript
运行
复制
import asyncio

async def async_procedure():
    process = await asyncio.create_subprocess_exec('ping', '-c', '2', 'google.com')
    await process.wait()
    print('async procedure done.')

loop = asyncio.get_event_loop()
loop.run_until_complete(async_procedure())
loop.close()

上面的代码工作得很好。其结果如下:

代码语言:javascript
运行
复制
PING google.com (...) 56(84) bytes of data.
64 bytes from ...: icmp_seq=1 ttl=46 time=34.8 ms
64 bytes from ...: icmp_seq=2 ttl=46 time=34.5 ms

--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 33.771/34.437/34.881/0.407 ms
Process done!

当我尝试删除process.wait()时:

代码语言:javascript
运行
复制
async def async_procedure():
    await asyncio.create_subprocess_exec('ping', '-c', '2', 'google.com')
    print('async procedure done.')

脚本不像预期的那样工作:

代码语言:javascript
运行
复制
Process done! # This line should be lastest line
PING google.com (...) 56(84) bytes of data.
64 bytes from ...: icmp_seq=1 ttl=46 time=21.1 ms
64 bytes from ...: icmp_seq=2 ttl=46 time=21.8 ms

--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 21.135/21.469/21.803/0.334 ms

但在一个非常类似的例子中没有问题:

代码语言:javascript
运行
复制
async def async_procedure():
    await asyncio.sleep(2)
    print('async procedure done')
  • 那么,为什么不等待asyncio.create_subprocess_exec()呢?

docs (https://docs.python.org/3/library/asyncio-task.html#coroutine)说:

结果=等待未来或结果=来自未来的产量-挂起协同线,直到将来完成,然后返回未来的结果,或引发异常,该异常将被传播。(如果取消了未来,它将引发CancelledError异常。)注意,任务是未来的,关于期货的一切都适用于任务。 -等待另一个coroutine生成另一个coroutine (或引发一个将被传播的异常)。coroutine表达式必须是对另一个协同线的调用。 返回表达式-使用等待或屈服产生一个结果到正在等待这个表达式的协同线。 引发异常-在协同线中引发一个异常,该异常正在等待或放弃。

  • 当协同线挂起和等待时,流程的流程究竟是什么?

下面是asyncio.create_subprocess_exec()和asyncio.sleep()的源代码。两者都是协同机制:

代码语言:javascript
运行
复制
@coroutine
def create_subprocess_exec(program, *args, stdin=None, stdout=None,
                           stderr=None, loop=None,
                           limit=streams._DEFAULT_LIMIT, **kwds):
    if loop is None:
        loop = events.get_event_loop()
    protocol_factory = lambda: SubprocessStreamProtocol(limit=limit,
                                                        loop=loop)
    transport, protocol = yield from loop.subprocess_exec(
                                            protocol_factory,
                                            program, *args,
                                            stdin=stdin, stdout=stdout,
                                            stderr=stderr, **kwds)
    return Process(transport, protocol, loop)


@coroutine
def sleep(delay, result=None, *, loop=None):
    """Coroutine that completes after a given time (in seconds)."""
    if delay == 0:
        yield
        return result

    if loop is None:
        loop = events.get_event_loop()
    future = loop.create_future()
    h = future._loop.call_later(delay,
                                futures._set_result_unless_cancelled,
                                future, result)
    try:
        return (yield from future)
    finally:
        h.cancel()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-23 18:44:39

你等着进程开始。你没等它结束。await process.wait()等待它完成。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48408639

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档