I believe your problem is because you use zmq before you fork. Let me explain:
- zerorpc uses pyzmq
- pyzmq, when possible, uses libzmq which is a C library
- libzmq uses C threads to process IOs.
- forking after zmq threads are created can often lead to deadlocks
When you call rpc_runner, you are using zerorpc which in turns initializes zmq.
After that, when you start subprocesses, you are technically forking
your own process. Which happens to fork everything, including all the
threads. As far I as know; on posix; its not really well defined what
happens when you fork with threads.
If you instanciate a new zmq context you will workaround the problem.
zerorpc follows the same principle and let you instanciate context
wrapping zmq.
This should workaround the problem:
diff --git a/gipc_zerorpc.py b/gipc_zerorpc.py
index fd2592a..e79de0d 100644
--- a/gipc_zerorpc.py
+++ b/gipc_zerorpc.py
@@ -7,7 +7,7 @@ class GipcZerorpcTest:
def __init__(self):
self._parent_state = 100
# Uncommenting this line causes child subprocesses
zerorpc_client to hang.
- # self.rpc_runner(0)
+ self.rpc_runner(0)
self.subprocess_initializer()
def subprocess_initializer(self):
@@ -21,8 +21,9 @@ class GipcZerorpcTest:
print("Finished!")
def rpc_runner(self, input):
+ ctx = zerorpc.Context()
print(f"Subprocess started with PID: {os.getpid()} and
subprocess ID: {input} with parent state: {self._parent_state}")
- zerorpc_client = zerorpc.Client()
+ zerorpc_client = zerorpc.Client(context=ctx)
zerorpc_client.connect("ipc:///tmp/test_zerorpc_server.sock")
print(f"ZeroRPCServer PID: {zerorpc_client.getpid()}")
I encourage you to fork BEFORE using zerorpc, but its up to you.