使用Cython与Asyncio(Python 3.4)

6

有人成功地将Cython与Asyncio协程配合使用吗? 我有一个在Python中运行良好的非常简单的示例,在Cython中却无法运行:它是以下单个文件,我使用Cython编译并执行。执行开始正确,但无法运行协程。 似乎Cython修改了“sometask”协程的类型,然后Asyncio和Inspect不像通常那样对待它。

#!/usr/bin/env python

import asyncio


@asyncio.coroutine
def sometask():
    counter = 0
    while True:
        print(counter)
        yield from asyncio.sleep(1)
        counter += 1

def runloop():
    loop = asyncio.get_event_loop()
    asyncio.async(sometask())
    try:
        print('Start loop')
        loop.run_forever()
    except KeyboardInterrupt:
        print('Aborted by user')
        loop.close()

更新: 目前我通过在asyncio/tasks.py文件中以不雅的方式修改,使其能够“工作”,其中检查对象是否为生成器的地方被修改,而事实上Cython将其作为内置函数。即使它具有与预期不同的类型,这个Cython对象仍然会完成asyncio协程的工作。


好像是个bug:https://groups.google.com/forum/#!topic/cython-users/3NdxAdz97eU - dano
谢谢,我复制粘贴了Stefan Behnel的答案,也许有人找到了解决这个问题的方法: "我猜这是asyncio中的一个bug。它特别处理“types.GeneratorType”,而Cython的生成器不属于该类型。请参见asyncio/coroutines.py中的“_COROUTINE_TYPES”和“iscoroutine()”。遗憾的是,在Python中没有生成器的ABC。Stefan" - MoriB
1个回答

4

幸运的是,Stefan Behnel在Cython主分支的最新版本中解决了这个问题。

编辑:解决所有问题的提交是c8a2d30806b4e479515d44ee827b3a1651ac8731

可能更合适的解决方案是在Python端进行处理,特别是在Asyncio中,识别生成器而不检查它们的类型。 完整的解决方案需要Python 3.4.2(确保> Python 3.4.0) 更多详情请见: https://groups.google.com/forum/#!topic/cython-users/g146SZHxRyM


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接