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

时间:2015-03-18 16:22:19

标签: python linux queue pipe fifo

我在Linux系统上运行了一个Python守护程序。 我想提供诸如" Bob"," Alice"等信息,并让守护程序打印" Hello Bob。"和#34; Hello Alice"到文件。

这必须是异步的。 Python守护进程必须等待信息并在收到信息时打印它。

实现这一目标的最佳方式是什么?

我在想一个命名管道或Queue库,但可能有更好的解决方案。

8 个答案:

答案 0 :(得分:6)

以下是使用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 :(得分:3)

有几个选项

1)如果守护程序应接受来自其他系统的消息,请将守护程序设为RPC服务器 - 使用xmlrpc / jsonrpc。

2)如果它都是本地的,您可以使用TCP套接字或命名PIPE。

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

答案 2 :(得分:0)

您可以使用一些机制,但一切都归结为使用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

用于非阻塞方式。

答案 3 :(得分:0)

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

(python 2.7)或

(python 3.3)

可能值得考虑。

答案 4 :(得分:0)

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

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

nc

的优点
  • 非常好用
  • IPC甚至在不同的编程语言之间
  • 内置于大多数Linux操作系统

实施例
关于deamon

nc -l 1234 > output.txt

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

echo HELLO | nc 127.0.0.1 1234

nc可以通过使用系统命令调用函数(可能是os.system)进行python并读取标准输出。

答案 5 :(得分:0)

为什么不使用信号?

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

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

答案 6 :(得分:0)

一种解决方案可能是使用asynchat library来简化服务器和客户端之间的调用。

以下是您可以使用的示例(改编自this site

deamon.py中,创建了一个ChatServer对象。每次连接完成时,都会创建一个ChatHandler对象,继承自asynchat.async_chat。此对象收集数据并将其填入self.buffer

当遇到特殊字符串调用终结符时,数据应该是完整的并且调用方法found_terminator。在这种方法中,您可以编写自己的代码。

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

daemon.py:

push

sender.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()

答案 7 :(得分:0)

每个人都提到FIFO-s(在Linux术语中称为管道)和XML-RPC,但是如果你现在就学习这些东西,你必须检查TCP / UDP / Unix套接字,因为它们是独立于平台的(在至少,TCP / UDP套接字是)。您可以查看this tutorial查看工作示例,或Python documentation,如果您想要朝着这个方向努力。它也很有用,因为大多数现代通信平台(XML-RPC,SOAP,REST)都使用这些基本的东西。