wim*_*wim 51 python sockets ipc pipe
在两个不同的python进程之间进行进程间通信的干净而优雅的方法是什么?我目前在操作系统中使用命名管道,但感觉有点hacky.我用dbus服务重写了我的东西,但是看起来当通过SSH会话远程运行代码时,它现在尝试初始化X11,这对于我想要做的事情来说似乎完全没有必要(它们与GUI无关).所以也许dbus有点太重量了.我正准备再次使用套接字重新设计,但它看起来很低级,所以我认为可能有一个更高级别的模块我可以导入和使用,我根本就不知道它的名字,我想我应该问SO第一..
我的要求是能够运行python foo.py并让这个过程就像守护进程那样做,并能够发送消息给它python foo.py --bar.后一个调用应该只是向现有进程发送一个消息并终止,可能带有0成功的返回代码或其他失败的代码(因此需要进行一些双向通信).
vse*_*har 93
该multiprocessing库提供了包装套接字的侦听器和客户端,允许您传递任意python对象.
您的服务器可以侦听接收python对象:
from multiprocessing.connection import Listener
address = ('localhost', 6000) # family is deduced to be 'AF_INET'
listener = Listener(address, authkey='secret password')
conn = listener.accept()
print 'connection accepted from', listener.last_accepted
while True:
msg = conn.recv()
# do something with msg
if msg == 'close':
conn.close()
break
listener.close()
Run Code Online (Sandbox Code Playgroud)
您的客户端可以发送命令作为对象:
from multiprocessing.connection import Client
address = ('localhost', 6000)
conn = Client(address, authkey='secret password')
conn.send('close')
# can also send arbitrary objects:
# conn.send(['a', 2.5, None, int, sum])
conn.close()
Run Code Online (Sandbox Code Playgroud)
zee*_*kay 38
不,zeromq是要走的路.好吃,不是吗?
import argparse
import zmq
parser = argparse.ArgumentParser(description='zeromq server/client')
parser.add_argument('--bar')
args = parser.parse_args()
if args.bar:
# client
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect('tcp://127.0.0.1:5555')
socket.send(args.bar)
msg = socket.recv()
print msg
else:
# server
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind('tcp://127.0.0.1:5555')
while True:
msg = socket.recv()
if msg == 'zeromq':
socket.send('ah ha!')
else:
socket.send('...nah')
Run Code Online (Sandbox Code Playgroud)
Bas*_*asj 15
根据@vsekhar 的回答,这是一个 Python 3 版本,其中包含更多详细信息和多个连接:
from multiprocessing.connection import Listener
listener = Listener(('localhost', 6000), authkey=b'secret password')
running = True
while running:
conn = listener.accept()
print('connection accepted from', listener.last_accepted)
while True:
msg = conn.recv()
print(msg)
if msg == 'close connection':
conn.close()
break
if msg == 'close server':
conn.close()
running = False
break
listener.close()
Run Code Online (Sandbox Code Playgroud)
from multiprocessing.connection import Client
import time
# Client 1
conn = Client(('localhost', 6000), authkey=b'secret password')
conn.send('foo')
time.sleep(1)
conn.send('close connection')
conn.close()
time.sleep(1)
# Client 2
conn = Client(('localhost', 6000), authkey=b'secret password')
conn.send('bar')
conn.send('close server')
conn.close()
Run Code Online (Sandbox Code Playgroud)
我会使用套接字;本地通信经过了高度优化,因此您不应该遇到性能问题,并且可以在需要时将应用程序分发到不同的物理节点。
关于“低级”方法,您是对的。但是您始终可以根据需要使用更高级别的包装器。XMLRPC可能是一个不错的候选者,但对于您要执行的任务来说,它可能有点过头了。
Twisted提供了一些很好的协议简单实现,例如LineReceiver(用于简单的基于行的消息)或更优雅的 AMP(顺便说一下,它被标准化并以不同的语言实现)。
| 归档时间: |
|
| 查看次数: |
48892 次 |
| 最近记录: |