2017-05-30 52 views
1

我想在Python(pyzmq)中使用ZeroMQ和多處理。作爲一個微型(不)工作的例子,我有一個服務器和客戶端類,它們都從multiprocessing.Process繼承。如果我運行此服務器進程似乎在接收呼叫msg = socket.receive_string()ZeroMQ掛在python多處理類/對象解決方案

#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() 

現在:客戶端作爲一個孩子的過程應該將消息發送到服務器,子進程應打印信息。在另一個(更復雜的)案例中,它甚至掛在了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實現和事實有關,即進程沒有共享內存。 如果在運行方法中實例化上下文,它將起作用。

這裏工作的例子:

#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對象。如果將上下文對象放入方法init,它將不起作用。

+0

你是對的,這正是我設法解決這個問題的方法,直到現在我都無法回答自己。由於未知的原因,所有ØMQ必須在該過程的運行時期間實例化。此外,我最終調用'init_zmq()'來重新定義鏈接到ØMQ(即上下文,套接字)的對象的屬性,將其定義爲'None'。這有點迂迴,但我認爲沒關係。 – paulkernstock