11.7 在��的Python解释器之间交互¶

问题¶

你在��的机器上��行�多个Python解释器实例,并希望能够在这些解释器之间通过消��交�数�。

解决方案¶

通过使用 multiprocessing.connection 模��以很容易的实现解释器之间的通信。 下�是一个简�的应答�务器例�:

from multiprocessing.connection import Listener
import traceback

def echo_client(conn):
    try:
        while True:
            msg = conn.recv()
            conn.send(msg)
    except EOFError:
        print('Connection closed')

def echo_server(address, authkey):
    serv = Listener(address, authkey=authkey)
    while True:
        try:
            client = serv.accept()

            echo_client(client)
        except Exception:
            traceback.print_exc()

echo_server(('', 25000), authkey=b'peekaboo')

然�客户端连接�务器并��消�的简�示例:

>>> from multiprocessing.connection import Client
>>> c = Client(('localhost', 25000), authkey=b'peekaboo')
>>> c.send('hello')
>>> c.recv()
'hello'
>>> c.send(42)
>>> c.recv()
42
>>> c.send([1, 2, 3, 4, 5])
>>> c.recv()
[1, 2, 3, 4, 5]
>>>

跟底层socket��的是,�个消�会完整�存(�一个通过send()��的对象能通过recv()�完整接�)。 �外,所有对象会通过pickle�列化。因此,任何兼容pickle的对象都能在此连接上�被��和接�。

讨论¶

目�有很多用�实现��消�传输的包和函数库,比如ZeroMQ�Celery等。 你还有�外一�选择就是自己在底层socket基础之上�实现一个消�传输层。 但是你想�简�一点的方案,那么这时候 multiprocessing.connection 就派上用场了。 仅仅使用一些简�的语���实现多个解释器之间的消�通信。

如果你的解释器�行在�一�机器上�,那么你�以使用�外的通信机制,比如Unix域套接字或者是Windows命�管�。 �想使用UNIX域套接字�创建一个连接,�需简�的将地�改写一个文件���:

s = Listener('/tmp/myconn', authkey=b'peekaboo')

�想使用Windows命�管��创建连接,�需�下�这样使用一个文件�:

s = Listener(r'\\.\pipe\myconn', authkey=b'peekaboo')

一个通用准则是,你��使用 multiprocessing �实现一个对外的公共�务。 Client() 和 Listener() 中的 authkey �数用�认��起连接的终端用户。 如果密钥�对会产生一个异常。此外,该模�最适�用�建立长连接(而�是大�的短连接), 例如,两个解释器之间�动�就开始建立连接并在处��个问题过程中会一直��连接状�。

如果你需�对底层连接�更多的控制,比如需�支�超时��阻塞I/O或其他类似的特性, 你最好使用�外的库或者是在高层socket上�实现这些特性。