質問

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.

EDIT2: there is a new explanation of this question: look at the bottom.

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:

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. 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:

class A:

from utils import messenger as m

class Foo():

[...]

def foo():

    [...]
    m.put(message)

class 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:

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.

Node A, the publisher:

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:

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

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top