我在Windows上使用asyncio,并且具有对命名管道的传输对象的引用:

class DataPipeHandler(asyncio.Protocol):
    def connection_made(self, trans):
        self.trans = trans # <<== this is a reference to a transport object of type _ProactorDuplexPipeTransport

loop = asyncio.get_event_loop()
server = loop.start_serving_pipe(lambda: DataPipeHandler(), r'\\.\pipe\test-pipe')


现在,我想使用self.trans来同步写入命名管道并从中读取数据。我怎样才能做到这一点?

对我而言,同步执行此操作很重要,因为这是我正在使用管道进行的RPC调用(写一些东西并迅速返回响应),并且我确实想阻止偶数循环的所有其他活动,直到此“管道RPC调用”为止”返回。
如果在完成此RPC调用之前不阻止事件循环的所有其他活动,我将产生不良的副作用,因为该循环将继续处理我不希望其处理的其他事件。

我想做的事情(写到管道然后读取)与从事件循环线程调用urllib2.urlopen(urllib2.Request('http://www.google.com')).read()的人非常相似-在这里,所有事件循环活动都将被阻止,直到我们从远程http服务器获得响应为止。

我知道我可以调用self.trans.write(data),但这不会同步写入数据(据我了解它不会阻塞)

谢谢。

编辑:在第一个评论之后,让我添加:

我知道我永远都不会阻塞事件循环,并且我可以使用同步原语来完成我想要的事情。但是,可以说您有一个事件循环,该事件循环并行执行10个不同的活动,并且其中一个正在执行某种RPC(如上所述),在完成此RPC之前,应阻止所有其他9个活动。所以我有2个选择:

(1)将您建议的同步原语(锁/信号灯/条件)添加到所有这10个活动中以使其同步。

(2)通过阻止写入,然后阻止从/向管道读取,来实现此RPC。 (假设我信任管道的另一侧)

我知道这不是使用事件循环的常用方法,但是在我的特定情况下,我认为(2)更好。 (逻辑更简单)

最佳答案

我认为您必须使用线程同步原语来确保整个循环(当前线程)被阻止。我认为最好的选择是使用线程队列和联接功能。

关于python - 如何执行*异步*对异步传输对象的读/写,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31177039/

10-15 05:27