2017-05-30 6 views
1

Python(pyzmq)でZeroMQをマルチプロセッシングと併用しようとしています。 minmal(ない)の動作例として、私はサーバクラスとクライアントクラスの両方がmultiprocessing.Processから継承されています。子プロセスとして、クライアントのメッセージを印刷する必要があり、サーバ子プロセスにメッセージを送信する必要があります:私はこれを実行する場合Pythonマルチプロセッシングクラス/オブジェクトソリューションでZeroMQがハングアップする

#mpzmq_class.py 

from multiprocessing import Process 
import zmq 


class Server(Process): 
    def __init__(self): 
     super(Server, self).__init__() 
     self.ctx = zmq.Context() 
     self.socket = self.ctx.socket(zmq.PULL) 
     self.socket.connect("tcp://localhost:6068") 

    def run(self): 
     msg = self.socket.recv_string() 
     print(msg) 


class Client(Process): 
    def __init__(self): 
     super(Client, self).__init__() 
     self.ctx = zmq.Context() 
     self.socket = self.ctx.socket(zmq.PUSH) 
     self.socket.bind("tcp://*:6068") 

    def run(self): 
     msg = "Hello World!" 
     self.socket.send_string(msg) 

if __name__ == "__main__": 
    s = Server() 
    c = Client() 
    s.start() 
    c.start() 
    s.join() 
    c.join() 

は今、サーバプロセスは、受信呼び出すmsg = socket.receive_string()でハングしているようです。別の(より複雑な)ケースでは、それはsocket.connect("...")-文でぶら下がっていました。

私が代わりにクラス/オブジェクトの機能を使用するためのスクリプトを書き換えた場合、それはうまく動作します:

# mpzmq_function.py 

from multiprocessing import Process 
import zmq 


def server(): 
    ctx = zmq.Context() 
    socket = ctx.socket(zmq.PULL) 
    socket.connect("tcp://localhost:6068") 
    msg = socket.recv_string() 
    print(msg) 


def client(): 
    ctx = zmq.Context() 
    socket = ctx.socket(zmq.PUSH) 
    socket.bind("tcp://*:6068") 
    msg = "Hello World!" 
    socket.send_string(msg) 

if __name__ == "__main__": 
    s = Process(target=server) 
    c = Process(target=client) 
    s.start() 
    c.start() 
    s.join() 
    c.join() 

が出力:

[email protected]:~$ python3 mpzmq_function.py 
Hello World! 

誰がこれで私を助けることができますか?マルチプロセッシングの使い方について私が理解できなかったことだと思います。

ありがとうございました!

答えて

1

同じ問題が発生します。 問題は、runメソッドはコンテキストオブジェクトにアクセスできないと思います。 多分、Cの実装と関係があり、プロセスには共有メモリがないという事実があります。 runメソッドでコンテキストをインスタンス化すると動作します。

ここで作業例:

#mpzmq_class.py 

from multiprocessing import Process 
import zmq 


class Base(Process): 
    """ 
    Inherit from Process and 
    holds the zmq address. 
    """ 
    def __init__(self, address): 
     super().__init__() 
     self.address = address 


class Server(Base): 
    def run(self): 
     ctx = zmq.Context() 
     socket = ctx.socket(zmq.PULL) 
     socket.connect(self.address) 
     msg = socket.recv_string() 
     print(msg) 


class Client(Base): 
    def run(self): 
     ctx = zmq.Context() 
     socket = ctx.socket(zmq.PUSH) 
     socket.bind(self.address) 
     msg = "Hello World!" 
     socket.send_string(msg) 


if __name__ == "__main__": 
    server_addr = "tcp://127.0.1:6068" 
    client_addr = "tcp://*:6068" 
    s = Server(server_addr) 
    c = Client(client_addr) 
    s.start() 
    c.start() 
    s.join() 
    c.join() 

私はあなたがまだrunメソッドから通常のPythonオブジェクトにアクセスできることを実証するために、基本クラスを追加しました。 contextオブジェクトをのinitメソッドに入れると、それは機能しません。

+0

あなたはそうです、それは私がこの問題を解決することができた方法です、今まで自分自身に答えることができませんでした。理由が不明なため、すべてのØMQはプロセスの実行中にインスタンス化する必要があります。さらに、私は 'init_zmq()'を呼び出して、ØMQにリンクされたオブジェクトの属性(コンテキスト、ソケット)を以前に 'None'と定義し直しました。これは少し迂回していますが、大丈夫だと思います。 – paulkernstock

関連する問題