【问题标题】:Submit a job to an asyncio event loop将作业提交到异步事件循环
【发布时间】:2015-09-15 13:00:44
【问题描述】:

我想将线程中的作业提交到 asyncio 事件循环(就像 run_in_executor 一样,但反过来)。

这是asyncio 文档中关于concurrency and multithreading 的内容:

要从不同的线程安排回调,应使用 BaseEventLoop.call_soon_threadsafe() 方法。 从不同线程调度协程的示例: loop.call_soon_threadsafe(asyncio.async, coro_func())

效果很好,但是协程的结果丢失了。

相反,可以使用一个函数将完成回调添加到由async(或ensure_future)返回的未来,以便线程可以通过concurrent.futures.Future 访问结果。

标准库中没有实现这样的功能是否有特殊原因?还是我错过了一种更简单的方法来实现这一目标?

【问题讨论】:

    标签: python multithreading python-asyncio


    【解决方案1】:

    我的请求成功了,run_coroutine_threadsafe 函数已实现here

    例子:

    def target(loop, timeout=None):
        future = asyncio.run_coroutine_threadsafe(add(1, b=2), loop)
        return future.result(timeout)
    
    async def add(a, b):
        await asyncio.sleep(1)
        return a + b
    
    loop = asyncio.get_event_loop()
    future = loop.run_in_executor(None, target, loop)
    assert loop.run_until_complete(future) == 3
    

    我最初发布了concurrent.futures.Executor的一个子类,仍然可以实现为:

    class LoopExecutor(concurrent.futures.Executor):
        """An Executor subclass that uses an event loop 
        to execute calls asynchronously."""
    
        def __init__(self, loop=None):
            """Initialize the executor with a given loop."""
            self.loop = loop or asyncio.get_event_loop()
    
        def submit(self, fn, *args, **kwargs):
            """Schedule the callable, fn, to be executed as fn(*args **kwargs).
            Return a Future object representing the execution of the callable."""
            coro = asyncio.coroutine(fn)(*args, **kwargs)
            return asyncio.run_coroutine_threadsafe(coro, self.loop)
    

    【讨论】:

    • 你想把这个放在问题中,所以它看起来不像是一个答案
    • 嗯,这有点像a partial answer to my own question,因为可能有更好的方法来实现同样的目标。
    • 如果你这样看,ok :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多