Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何向Python守护进程提供信息?_Python_Linux_Queue_Pipe_Fifo - Fatal编程技术网

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

如何向Python守护进程提供信息?,python,linux,queue,pipe,fifo,Python,Linux,Queue,Pipe,Fifo,我有一个运行在Linux系统上的Python守护进程。 我想输入诸如“Bob”、“Alice”等信息,并让守护进程将“Hello Bob”和“Hello Alice”打印到文件中 这必须是异步的。Python守护进程必须等待信息,并在收到某个信息时将其打印出来 实现这一目标的最佳方式是什么 我在考虑命名管道或队列库,但可能有更好的解决方案。有一些机制可以使用,但一切都归结为使用IPC(进程间通信) 现在,您将使用的实际机制取决于您可以实现的细节,一个好的解决方案是使用类似zmq的东西 检查zmq

我有一个运行在Linux系统上的Python守护进程。 我想输入诸如“Bob”、“Alice”等信息,并让守护进程将“Hello Bob”和“Hello Alice”打印到文件中

这必须是异步的。Python守护进程必须等待信息,并在收到某个信息时将其打印出来

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


我在考虑命名管道或
队列
库,但可能有更好的解决方案。

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

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

检查zmq上发布/订阅的以下示例

还有这个


对于非阻塞方式

以下是使用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

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

(python 2.7)或

(python 3.3)


这可能值得考虑。

我不擅长python,因此我想与大家分享
**通用进程间通信**

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

nc的优点

  • 非常容易使用
  • IPC即使在不同的编程语言之间
  • 内置于大多数linux操作系统上
示例
论执事

nc -l 1234 > output.txt
来自其他程序或shell/terminal/script

echo HELLO | nc 127.0.0.1 1234
nc可以通过使用系统命令调用函数(可能是os.system)和读取标准输出来使用python。

为什么不使用信号

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


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

有几个选项

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

2) 如果都是本地的,则可以使用TCP套接字或命名管道


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

一种解决方案是使用简化服务器和客户端之间调用的

下面是一个您可以使用的示例(改编自)

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

当遇到一个特殊的字符串调用终止符时,数据应该是完整的,并调用方法
found\u terminator
。在这种方法中,您可以编写自己的代码

sender.py
中,创建一个继承自
asynchat.async\u 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()
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)
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()
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套接字是独立的)。如果您想朝这个方向前进,您可以查看工作示例或。它也很有用,因为大多数现代通信平台(XML-RPC、SOAP、REST)都使用这些基本的东西

谢谢,这似乎是最直接的答案。我将尝试一下。它将永远写
Hello Alice
,因为
的范围为True:
不,它不会。它的工作原理和上面的演示一样。看起来很整洁。但由于它不是一个标准模块,我不知道在我无法更改很多内容的生产环境中,这是否能满足我的需要。因为op希望向守护进程发送一些文本,并且有更多的字符串,而不是信号:)抱歉,我应该更频繁地查看此网站,我要做的是将我想要发送给demon的文本插入一个配置文件(您可以使用shell中的echo来执行此操作。(我可能会将配置文件存储在~/.demon_name/)下)然后指示程序在收到sighup后重新打开配置文件并解析其中的字符串。Python拥有自己的TCP/UDP/Unix套接字通信层,以及所有流行的编程语言。请不要从shell脚本以外的脚本语言中使用NC。以下是如何使用Python中的套接字: