Python中的进程间通信

130 投票
8 回答
124912 浏览
提问于 2025-04-16 22:46

有什么好的方法可以让两个独立的Python运行环境之间进行沟通呢?以下是尝试过的一些方法:

  • 通过命名管道进行读写,比如使用 os.mkfifo (感觉有点像变通的办法)
  • 使用 dbus 服务(在桌面上有效,但对于无头模式来说太复杂了)
  • 使用套接字(感觉太底层了;肯定有更高级的模块可以用吧?)

我的基本需求是能够像守护进程一样运行 python listen.py,并能够接收来自 python client.py 的消息。客户端只需向现有进程发送一条消息并结束,成功时返回代码 0,失败时返回非零代码(也就是说,需要双向通信)。

8 个回答

34

根据@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()

客户端

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()
61

不,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')
197

multiprocessing库提供了一些功能,可以让你在程序中同时运行多个任务。这个库里有一些叫做监听器和客户端的东西,它们可以处理网络连接,让你可以传递任意的Python对象。

你的服务器可以设置为监听,接收Python对象:

from multiprocessing.connection import Listener

address = ('localhost', 6000)     # family is deduced to be 'AF_INET'
listener = Listener(address, authkey=b'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()

你的客户端可以把命令作为对象发送出去:

from multiprocessing.connection import Client

address = ('localhost', 6000)
conn = Client(address, authkey=b'secret password')
conn.send('close')
# can also send arbitrary objects:
# conn.send(['a', 2.5, None, int, sum])
conn.close()

撰写回答