【问题标题】:Using Asyncio subprocess in a pyramid view在金字塔视图中使用 Asyncio 子进程
【发布时间】:2016-10-17 07:55:44
【问题描述】:

我正在尝试在金字塔视图中运行 asyncio 子进程,但视图挂起并且异步任务似乎永远无法完成。我可以在金字塔视图之外运行这个示例,它可以工作。

话虽如此,我最初使用loop = asyncio.get_event_loop() 进行了测试,但这告诉我RuntimeError: There is no current event loop in thread 'Dummy-2'

这里肯定有一些我不完全理解的东西。就像视图线程可能与主线程不同,所以get_event_loop 不起作用。

那么有人知道为什么我的异步任务在这种情况下可能不会产生结果吗?这是一个幼稚的例子。

@asyncio.coroutine
def async_task(dir):
    # This task can be of varying length for each handled directory
    print("Async task start")
    create = asyncio.create_subprocess_exec(
        'ls',
        '-l',
        dir,
        stdout=asyncio.subprocess.PIPE)
    proc = yield from create

    # Wait for the subprocess exit
    data = yield from proc.stdout.read()
    exitcode = yield from proc.wait()
    return (exitcode, data)


@view_config(
    route_name='test_async',
    request_method='GET',
    renderer='json'
)
def test_async(request):
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    dirs = ['/tmp/1/', '/tmp/2/', '/tmp/3/']
    tasks = []
    for dir in dirs:
        tasks.append(asyncio.ensure_future(async_task(dir), loop=loop))

    loop.run_until_complete(asyncio.gather(*tasks))
    loop.close()
    return

【问题讨论】:

  • Pyramid 框架与 asyncio 不兼容,没有理由一起使用。
  • 我有一种感觉,可能是这样的。我还是有兴趣为什么?我注意到 uWSGI 服务器有一个使用 asyncio 的实验性功能,这会改变它的行为吗?
  • 没有。 Pyramid 是一个 WSGI 框架。 WSGI 按照标准定义是同步的。

标签: pyramid python-3.5 python-asyncio


【解决方案1】:

在你看来,你正在调用loop.run_until_complete,所以很明显它会阻塞直到完成!

如果你想在 WSGI 应用程序中使用 asyncio,那么你需要在另一个线程中这样做。例如,您可以启动一个包含事件循环的线程并执行您的异步代码。 WSGI 代码都是同步的,因此任何异步代码都必须以这种方式完成,但有它自己的问题,或者你可以忍受它像现在这样阻塞请求线程。

【讨论】:

  • 我实际上对阻塞没问题。作为我在代码中的非天真的示例,我在文件列表上运行了一个子进程。每个文件的大小不同,处理时间也不同。因此,并行运行任务是完成这项工作的一种有效方式。
猜你喜欢
  • 1970-01-01
  • 2012-11-18
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
  • 2018-08-05
  • 2017-07-03
相关资源
最近更新 更多