在不同的python解释器之间进行通信
当我们运行多个python解释器实例,还有可能是在不同的机器上时,我们可能会需要通过消息在不同的解释器之间交换数据。
我们需要的不是复杂的消息队列,而是简单的交换无损信息的话,那么multiprocessing.connection库正是我们所需要的。只需要使用几个简单的原语便可以轻松将各个解释器联系在一起并交换数据了。
下面看示例:
#一号解释器运行扮演服务器角色
from multiprocessing.connection import Listener
def client(conn):
while True:
try:
msg = conn.recv()
print(f'Server receive the msg:{msg}')
conn.send('Got it')
except:
print('Server Error')
break
def server(address,authkey):
serv = Listener(address,authkey=authkey)
while True:
try:
clients = serv.accept()
client(clients)
except:
print('Server Error')
break
server(('',25000),authkey=b'AmosH'
上面的代码是一号解释器的服务器代码,下面是运行时的效果图:
可以看到,所有由send()方法发送的对象都完整无损的被recv()方法接收到了。任何同pickle兼容的对象都可以在连接之间传递和接收。
如果知道这些解释器会运行在同一台机器上,那么可以利用网络作为替代方案。比如使用UNIX的域socket或者Windows的命名管道,只要简单的把地址改为文件名就可以了,示例如下:
#UNIX
s = Listener('/tmp/myconn',authkey = authkey)
#Windows
s = Listener(r'\\.\pipe\myconn',authkey = authkey)
一般来说,不应该使用multiprocessing模块来实现面向公众型的服务。传递给Client()和Server()的authkey在这里是为了帮助认证连接两端的节点。使用错误的**来连接会产生异常。
注意,这个模块最好适用于能够长时间运行的连接,而不是大量的短连接。
如果需要对连接实现更多的底层控制,那么就不要使用multiprocessing模块。比方说,如果要支持超时、非阻塞I/O或者任何类似的特性,那么最好使用另一个不同的库或者直接在socket上实现这些特性。
微信公众号:进击的代码Amos
每天更新Java、python学习资料、技术干货。分享见解,共同成长。
关注公众号,免费获取众多电子版经典教材。