Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在没有大量回调和同步等待的情况下,从另一个线程调度异步IO协程_Python_Multithreading_Asynchronous_Python Asyncio - Fatal编程技术网

Python 在没有大量回调和同步等待的情况下,从另一个线程调度异步IO协程

Python 在没有大量回调和同步等待的情况下,从另一个线程调度异步IO协程,python,multithreading,asynchronous,python-asyncio,Python,Multithreading,Asynchronous,Python Asyncio,我必须要求澄清我的问题 我有一个发送消息的协同程序send。我想在loop2(在线程2中运行)的loop1(在线程1中运行)中调度它: asyncio.run\u coroutine\u threadsafe返回的future是一个并发的.futures.future,不能异步等待 所以问题是:我如何正确地等待未来和/或我应该如何安排我的发送以获得一个可等待的对象 我知道我能做到: async def send_threadsafe(...): future = ... resu

我必须要求澄清我的问题

我有一个发送消息的协同程序
send
。我想在
loop2
(在线程2中运行)的
loop1
(在线程1中运行)中调度它:

asyncio.run\u coroutine\u threadsafe
返回的
future
是一个
并发的.futures.future
,不能异步等待

所以问题是:我如何正确地等待
未来
和/或我应该如何安排我的
发送
以获得一个可等待的对象

我知道我能做到:

async def send_threadsafe(...):
    future = ...
    result = await current_loop.run_in_executor(None, future.result)
但是有没有一种不用另一个线程的方法呢?因为
run\u in\u executor
future.result
发送到线程池,我不想使用该线程池


我不想使用
call\u soon\u threadsafe
的原因是它需要创建几个回调。首先,计划在
loop1
中运行
send
。其次,在
loop1
中运行
send
,并在
loop2
中安排第三次回调。第三,将结果设置为在第一次回调中创建的未来(因为asyncio未来不是线程安全的,我无法从
loop1
设置结果)。

您可以使用
asyncio.wrap\u future
从并发未来获取asyncio未来:

async def send_threadsafe(self, message, destination, *, loop=loop):
    concurrent = asyncio.run_coroutine_threadsafe(
        send(message), loop=destination)
    return await asyncio.wrap_future(concurrent, loop=loop)
通过实现asyncio执行器,也可以实现同样的目标:

from concurrent.futures import Executor

class AsyncioExecutor(Executor):

    def __init__(self, loop):
        self.loop = loop

    def submit(self, fn, *args, **kwargs):
        coro = fn(*args, **kwargs)
        return asyncio.run_coroutine_threadsafe(coro, self.loop)
例如:

executor = AsyncioExecutor(remote_loop)
result = await loop.run_in_executor(executor, send, message)

谢谢,这正是我想要的!顺便说一下,在您的第一个示例中,
async def send_threadsafe()
不应该只是
def send_threadsafe()
?@Zelta Oops,它是固定的!
executor = AsyncioExecutor(remote_loop)
result = await loop.run_in_executor(executor, send, message)