0

その問題に対する答えを数時間探していましたが、解決できなかったので、この質問をここに投稿する必要があります。それは些細なことだと確信しています。

私が取り組んでいるプロジェクトには多くのクラスとスレッドがあり、それに小さなクラスを追加しています。これらのクラスは、プロジェクトのエンジンを使用して異なるスレッドで実行されますが、クラス間で同期する必要があります。つまり、クラス A はクラス B にメッセージを送信できる必要があります。それらは異なるモジュールにもあります。

EDIT2:この質問の新しい説明があります:一番下を見てください。

私はPythonの非常に初心者であり、キューオブジェクト(Queue.Queue())を共有し、その内容を無限ループで調べることでこれを解決しようとしました。このオブジェクトとメソッドgetおよびputを使用して非常に単純なモジュールを作成しました。

メッセンジャーモジュール:

import Queue

MessageQueue = Queue.Queue()

def GetMessage():
    return MessageQueue.get()

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

2つの異なるクラス(インポートメッセンジャー)で使用しますが、グローバル変数ではないため、「MessageQueue」オブジェクトには異なるクラスで異なるインスタンスがあると想定しています。これらのクラスは異なるキューで動作しているように見えるためです。

そのようなオブジェクト間で 2 つのクラスを同期する方法 (このキューをグローバルにする代わりに、より良い方法があるかもしれません)。

EDIT1 - ここにクラスがあります:

クラスA:

from utils import messenger as m

class Foo():

[...]

def foo():

    [...]
    m.put(message)

クラス B:

from utils import messenger

class Bar():

[...]

def bar():

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

EDIT2:私は自分の問題をもう少しよく理解しているので、ここに更新があります:

両方のクラスは、異なるプロセスで別個のプログラムとして実行されます (グローバル変数を共有していない理由を説明できるかもしれません:))。

問題は残ります: 2 つの異なるプログラム間でどのように同期するのですか? 私が考える唯一の解決策は、ディスク上にファイルを作成し、プロセス間でそれを読み取ることですが、非常に信頼性が低く (ロックなど)、遅いようです。

別のアプローチを提案できますか?

4

2 に答える 2

4

OK、 Zero MQライブラリを使用して問題を解決しました。

パブリッシャーであるノード 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)

ノード 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))

この設定は、私が望んでいたことを実行します。つまり、あるプログラムから別のプログラムにシグナルを伝達し、非常に適切な時間で実行します (この非常に単純なメッセージ、2 つの整数のタプルは、約 0.5 ミリ秒で送信されます)。

2 つの重要なこと:

  1. サブスクライブは、メッセージを受信するために「承認」されている必要があります。これは、メッセージの最初の値をフィルタリングすることによって行われます
  2. パブリッシャーは「バインディング」、サブスクライバーはソケットに「接続」
于 2013-08-02T23:27:36.913 に答える
0

オブジェクトをグローバルにせずに複数のインスタンス (異なるクラス、同じクラスなど) 間でオブジェクトを共有する方法は同じです。オブジェクトを各インスタンスのコンストラクターに渡します。例えば:

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)

bar1bar2bar1.foo、およびbar2.fooすべてが同じmオブジェクトを持っています。

于 2013-08-02T01:01:38.177 に答える