如何将信息提供给Python守护进程?

我有一个运行在Linux系统上的Python守护进程。 我想提供诸如“Bob”,“Alice”等的信息,并且具有守护进程打印“Hello Bob”。 和“你好爱丽丝”的文件。

这必须是asynchronous的。 Python守护进程必须等待信息,并在收到信息时进行打印。

什么是实现这个目标的最好方法?

我正在考虑命名pipe道或Queue库,但可能有更好的解决scheme。

以下是你如何使用fifo做到这一点:

 # receiver.py import os import sys import atexit # Set up the FIFO thefifo = 'comms.fifo' os.mkfifo(thefifo) # Make sure to clean up after ourselves def cleanup(): os.remove(thefifo) atexit.register(cleanup) # Go into reading loop while True: with open(thefifo, 'r') as fifo: for line in fifo: print "Hello", line.strip() 

你可以在shell会话中像这样使用它

 $ python receiver.py & $ echo "Alice" >> comms.fifo Hello Alice $ echo "Bob" >> comms.fifo Hello Bob 

有几个选项

1)如果守护进程应该接受来自其他系统的消息,则使守护进程成为RPC服务器 – 使用xmlrpc / jsonrpc。

2)如果全部是本地的,则可以使用TCP套接字或命名PIPE。

3)如果同时有大量的客户端连接,可以使用select.epoll。

有几个机制可以使用,但一切归结为使用IPC(进程间通信)。

现在,您将使用的实际机制取决于您可以实现的细节,但是使用类似zmq的解决方案是一个很好的解决方案。

检查zmq上的pub / sub上的以下示例

http://learning-0mq-with-pyzmq.readthedocs.org/en/latest/pyzmq/patterns/pubsub.html

也是这个

http://learning-0mq-with-pyzmq.readthedocs.org/en/latest/pyzmq/multisocket/zmqpoller.html

为非阻塞的方式。

python有一个内置的rpc库(使用xml进行数据编码)。 文档写得很好; 那里有一个完整的例子:

(python 2.7)或者

(python 3.3)

这可能值得考虑。

我不擅长python,所以我想分享一下
**通用进程间通信**

nc aka netcat是一个服务器客户端模型程序,允许通过网络发送文本,文件等数据。

nc优点

  • 非常容易使用
  • IPC甚至在不同的编程语言之间
  • 内置在大多数Linux操作系统上


在deamon

 nc -l 1234 > output.txt 

从其他程序或shell /终端/脚本

 echo HELLO | nc 127.0.0.1 1234 

nc可以通过使用系统命令调用函数(可以是os.system)来读取stdout。

为什么不使用信号?

我不是一个Python程序员,但可以在守护进程中注册一个信号处理程序,然后从终端发出信号。 只要使用SIGUSR或SIGHUP或类似的。

这是您用来旋转日志文件或类似的常用方法。

一个解决方案可能是使用简化服务器和客户端之间的通话的asynchat库 。

这里是一个你可以使用的例子(改编自这个网站 )

deamon.py ,创建一个Chatserver对象。 每次连接完成后, ChatHandler创建一个ChatHandler对象,并从asynchat.async_chat继承。 该对象收集数据并将其填充到self.buffer

遇到一个特殊的字符串调用终止符时,数据应该是完整的,方法found_terminator被调用。 在这个方法中,你编写自己的代码。

sender.py ,创建一个从asynchat.async_chat继承的ChatClient对象,在构造函数中设置连接,定义终结符(以防服务器回答!),并调用push方法发送数据。 您必须将终止符字符串附加到服务器的数据,以了解服务器何时可以停止读取数据。

daemon.py:

 import asynchat import asyncore import socket # Terminator string can be changed here TERMINATOR = '\n' class ChatHandler(asynchat.async_chat): def __init__(self, sock): asynchat.async_chat.__init__(self, sock=sock) self.set_terminator(TERMINATOR) self.buffer = [] def collect_incoming_data(self, data): self.buffer.append(data) def found_terminator(self): msg = ''.join(self.buffer) # Change here what the daemon is supposed to do when a message is retrieved print 'Hello', msg self.buffer = [] class Chatserver(asyncore.dispatcher): def __init__(self, host, port): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.bind((host, port)) self.listen(5) def handle_accept(self): pair = self.accept() if pair is not None: sock, addr = pair print 'Incoming connection from %s' % repr(addr) handler = ChatHandler(sock) server = Chatserver('localhost', 5050) print 'Serving on localhost:5050' asyncore.loop() 

sender.py:

 import asynchat import asyncore import socket import threading # Terminator string can be changed here TERMINATOR = '\n' class ChatClient(asynchat.async_chat): def __init__(self, host, port): asynchat.async_chat.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.connect((host, port)) self.set_terminator(TERMINATOR) self.buffer = [] def collect_incoming_data(self, data): pass def found_terminator(self): pass client = ChatClient('localhost', 5050) # Data sent from here client.push("Bob" + TERMINATOR) client.push("Alice" + TERMINATOR) 

大家都提到FIFO-s(在Linux术语中命名为管道)和XML-RPC,但是如果你现在正在学习这些东西,那么你也必须检查TCP / UDP / Unix套接字,因为它们是独立于平台的(至少TCP / UDP套接字是)。 如果你想要朝这个方向努力,你可以查看这个教程的一个工作示例或Python文档 。 由于大多数现代通信平台(XML-RPC,SOAP,REST)都使用这些基本的东西,所以它也很有用。