Python进程间查询/控制

6 投票
2 回答
9872 浏览
提问于 2025-04-16 04:39

我有一个基于Python的服务程序,它在处理很多输入输出的操作(叫做多路复用IO)。

我想从另一个Python脚本中查询这个服务程序的状态或信息,或者控制它的处理方式(比如暂停、关闭、改变一些参数等等)。

用Python发送控制消息(比如“从现在开始你这样处理!”)和查询处理结果(比如“那个结果是什么?”)的最佳方法是什么呢?

我听说过命名管道可能可以用,但对命名管道了解不多,尤其是在Python中,不知道有没有更好的选择。

这个后台服务程序和前端都是我自己编写的,所以所有的选择都是开放的 :)

我使用的是Linux系统。

2 个回答

3

在Python中,做进程间通信(IPC)最好的方法是使用消息队列,下面是具体的做法。

首先是服务器程序 server.py(在运行 client.py 和 interact.py 之前先运行这个)。

from multiprocessing.managers import BaseManager
import Queue
queue1 = Queue.Queue()
queue2 = Queue.Queue()
class QueueManager(BaseManager): pass
QueueManager.register('get_queue1', callable=lambda:queue1)
QueueManager.register('get_queue2', callable=lambda:queue2)
m = QueueManager(address=('', 50000), authkey='abracadabra')
s = m.get_server()
s.serve_forever()

接下来是用于输入输出交互的程序 interact.py。

from multiprocessing.managers import BaseManager
import threading
import sys
class QueueManager(BaseManager): pass
QueueManager.register('get_queue1')
QueueManager.register('get_queue2')
m = QueueManager(address=('localhost', 50000),authkey='abracadabra')
m.connect()
queue1 = m.get_queue1()
queue2 = m.get_queue2()

def read():
    while True:
        sys.stdout.write(queue2.get())

def write():
    while True:
        queue1.put(sys.stdin.readline())
threads = []

threadr = threading.Thread(target=read)
threadr.start()
threads.append(threadr)

threadw = threading.Thread(target=write)
threadw.start()
threads.append(threadw)

for thread in threads:
    thread.join()

最后是客户端程序 Client.py。

from multiprocessing.managers import BaseManager
import sys
import string
import os

class QueueManager(BaseManager): pass
QueueManager.register('get_queue1')
QueueManager.register('get_queue2')
m = QueueManager(address=('localhost', 50000), authkey='abracadabra')
m.connect()
queue1 = m.get_queue1()
queue2 = m.get_queue2()


class RedirectOutput:
    def __init__(self, stdout):
        self.stdout = stdout
    def write(self, s):
        queue2.put(s)

class RedirectInput:
    def __init__(self, stdin):
        self.stdin = stdin
    def readline(self):
        return queue1.get()

# redirect standard output

sys.stdout = RedirectOutput(sys.stdout)

sys.stdin = RedirectInput(sys.stdin)

# The test program which will take input and produce output 
Text=raw_input("Enter Text:")
print "you have entered:",Text
def x():
    while True:
        x= raw_input("Enter 'exit' to end and some thing else to continue")
        print x
        if 'exit' in x:
            break
x()

这个方法可以用来在网络上或同一台机器上的两个进程之间进行通信。记住,交互程序和服务器程序在你手动结束之前是不会自动停止的。

10

管道和命名管道是不同进程之间沟通的好方法。管道的工作方式就像共享内存缓冲区,但它的接口像是每一端都有一个简单的文件。一个进程在管道的一端写入数据,另一个进程在另一端读取这些数据。

命名管道和上面的管道类似,不同之处在于这个管道实际上和你电脑上的一个真实文件关联在一起。

更多详细信息可以查看

在Python中,命名管道文件是通过os.mkfifo这个调用创建的。

x = os.mkfifo(filename)

在子进程和父进程中打开这个管道作为文件。

out = os.open(filename, os.O_WRONLY)
in = open(filename, 'r')

写入数据。

os.write(out, 'xxxx')

读取数据。

lines = in.readline( )

编辑:添加来自StackOverflow的链接。

你可能还想了解更多关于“IPC和Python”的内容。

撰写回答