简体   繁体   English

Python:在进程之间共享消息

[英]Python: sharing message between processes

I've been searching for answer to that problem for few hours but couldn't solve it so I have to post here this question, I'm sure it's trivial. 我一直在寻找这个问题的答案几个小时但无法解决它所以我必须在这里发布这个问题,我相信这是微不足道的。

The project I work with has many classes and threads and I'm adding small classes to it. 我使用的项目有很多类和线程,我正在为它添加小类。 Those classes are executed in different threads with project's engine but I need them to synchronize between themselves - that is class A should be able to send a message to class B. They are also in different modules. 这些类在项目引擎的不同线程中执行,但我需要它们在它们之间进行同步 - 即A类应该能够向B类发送消息。它们也在不同的模块中。

EDIT2: there is a new explanation of this question: look at the bottom. 编辑2:这个问题有一个新的解释:看看底部。

I am really very beginner in python and I tried to solve this by sharing queue object (Queue.Queue()) and examining it's content in endless loops, I made very simple module with this object and methods get and put: 我在python中真的非常初学者,我试图通过共享队列对象(Queue.Queue())并在无限循环中检查它的内容来解决这个问题,我用这个对象和方法得到并放置了非常简单的模块:

messenger module: 信使模块:

import Queue

MessageQueue = Queue.Queue()

def GetMessage():
    return MessageQueue.get()

def PutMessage(message):
    MessageQueue.put(message)
    return

and use it in two different classes (import messenger), but since it's not global variable, I assume that 'MessageQueue' object has different instances in different classes. 并在两个不同的类(import messenger)中使用它,但由于它不是全局变量,我假设'MessageQueue'对象在不同的​​类中有不同的实例。 Because those classes seems working on different queues. 因为这些类似乎在不同的队列上工作。

How to synchronize two classes with such object between (maybe there is a pretier way instead just making this queue global)? 如何在这两个类之间同步这样的对象(也许有一种更好的方式,而只是让这个队列全局化)?

EDIT1 - here are classes: EDIT1 - 这是课程:

class A: A类:

from utils import messenger as m

class Foo():

[...]

def foo():

    [...]
    m.put(message)

class B: B级:

from utils import messenger

class Bar():

[...]

def bar():

    [...]
    while True:           
       print(str(m.get()))

EDIT2: Since I understand my problem a bit better now, here is an update: EDIT2:既然我现在对我的问题了解得更好了,这里有一个更新:

Both classes are run as distinct programs in different processes (what may explain why the are not sharing global variables :)). 这两个类在不同的进程中作为不同的程序运行(这可以解释为什么不共享全局变量:))。

So the problem remains: how to synchronize between two different programs? 所以问题仍然存在:如何在两个不同的程序之间进行同步? The only solution I think of is to make a file on a disc and read it between processes, but it seems very unreliable (locks etc.) and slow. 我想到的唯一解决方案是在光盘上创建一个文件并在进程之间读取它,但它看起来非常不可靠(锁等)并且速度很慢。

Can you suggest me different approach? 你能建议我采用不同的方法吗?

Ok, I solved the problem using Zero MQ library. 好的,我使用Zero MQ库解决了这个问题。

Node A, the publisher: 节点A,发布者:

import zmq, time
from datetime import datetime

context = zmq.Context()

#create this node as publisher
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:25647")


for i in range(300):
   message = ("%d, %d" % (1, i))
   print str(datetime.now().time()) + "> sending: " + message
   socket.send(message)
   time.sleep(1)

Node B, the receiver: 节点B,接收器:

import zmq, time
from datetime import datetime

context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect("tcp://localhost:25647")

#filter message for particular subscriber ('1')
socket.setsockopt(zmq.SUBSCRIBE, '1')

while True:
    message = socket.recv()
    print(str(datetime.now().time()) + "> received: " + str(message))

This setting does what I wanted, that is, it conveys signal from one program to another and it does it in quite good time (this very simple message, tuple of two integers, is sent in around 0.5 ms). 这个设置做了我想要的,也就是说,它将信号从一个程序传送到另一个程序,并且它在相当好的时间内完成(这个非常简单的消息,两个整数的元组,在大约0.5毫秒内发送)。

Two important things: 两件重要的事情:

  1. subscribe have to be "authorized" to receive message - it is done by filtering the first value of message 订阅必须被“授权”才能接收消息 - 它是通过过滤消息的第一个值来完成的
  2. publisher is "binding", subscriber "connecting" to socket 发布者是“绑定”,订阅者“连接”到套接字

The way to share any object among multiple instances (of different classes, of the same class, whatever) without making it global is the same: Pass the object into each instance's constructor. 在多个实例(不同类,同一类,无论什么)之间共享任何对象而不使其全局化的方法是相同的:将对象传递到每个实例的构造函数中。 For example: 例如:

class Foo(object):

    def __init__(self, m):
        self.m = m
        # ...

    # ...

    def foo(self):
        # ...
        self.m.put(message)
        # ...

# ...

class Bar(object):

    def __init__(self, m):
        self.m = m
        self.foo = Foo(m)
        # ...

    # ...

    def foo(self):
        # ...
        self.m.put(message)
        # ...

# ...

m = Queue.Queue()
bar1 = Bar(m)
bar2 = Bar(m)

Now bar1 , bar2 , bar1.foo , and bar2.foo all have the same m object. 现在bar1bar2bar1.foobar2.foo都具有相同的m对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM