I found this example code that shows the usage of Python's multiprocessing
together with ZeroMQ
:
import zmq
import time
from multiprocessing import Process
def server():
port="5556"
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:%s" % port)
print("Running server on port: ", port)
# serves only 5 request and dies
for reqnum in range(5):
# Wait for next request from client
message = socket.recv()
print("Received request #%s: %s" % (reqnum, message))
socket.send_string("World from %s" % port)
def client():
port="5556"
context = zmq.Context()
print("Connecting to server with port %s" % port)
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:%s" % port)
for request in range(20):
print("Sending request ", request, "...")
socket.send_string("Hello")
message = socket.recv()
print("Received reply ", request, "[", message, "]")
time.sleep(1)
if __name__ == "__main__":
Process(target=server).start()
Process(target=client).start()
This works well, but I would like to encapsulate the functions in classes, like so:
import zmq
import time
from multiprocessing import Process
class Server:
def run(self, socket):
port = "5556"
# serves only 5 request and dies
for reqnum in range(5):
# Wait for next request from client
message = socket.recv()
print("Received request #%s: %s" % (reqnum, message))
socket.send_string("World from %s" % port)
class Client:
def run(self, socket):
for request in range(20):
print("Sending request ", request, "...")
socket.send_string("Hello")
message = socket.recv()
print("Received reply ", request, "[", message, "]")
time.sleep(1)
if __name__ == "__main__":
port = "5556"
server = Server()
client = Client()
context = zmq.Context()
server_socket = context.socket(zmq.REP)
server_socket.bind("tcp://*:%s" % port)
print("Running server on port: ", port)
context = zmq.Context()
print("Connecting to server with port %s" % port)
client_socket = context.socket(zmq.REQ)
client_socket.connect("tcp://localhost:%s" % port)
Process(target=server.run, args=(server_socket,)).start()
Process(target=client.run, args=(client_socket,)).start()
But this results in following error message:
TypeError: no default __reduce__ due to non-trivial __cinit__
I researched a little bit and thought it would be because I don't share variables between processes, but I actually don't share anything. The processes should be independent to each other and all communications should run using ZeroMQ
.