Reputation: 31
Basically I have this problem:
I use ZMQ to use a PUB/SUB
formal pattern to publish some pieces of data to other programs. First class, i.e. a Server waits for a client to .connect()
and when the client connects, Server sends the data to the Client.
I use ZMQ REQ/REP
to synchronize Server and Client.
This is Server.py
:
class PublishThread (threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
socketPub.bind("tcp://127.0.0.1:4002")
syncservice.bind('tcp://127.0.0.1:5001')
def run(self):
while True:
subscribers = 0
topic = b"PHONEBOOK"
while subscribers < 1:
# Here we wait for client to connect. If the client doesn't
#connect, this is where this thread will "hang"
syncservice.recv()
# Send response to client
syncservice.send(b'')
subscribers += 1
socketPub.send_multipart([topic, data1])
subscribers = 0
Q1: How can I stop this thread when I want to exit my program?
Because when I want to exit my program, program "hangs" because thread is still running and waiting for a client.
Q2: How do you think that it will be best to implement this?
Q3: Is there any other way than REQ/REP
?
Upvotes: 3
Views: 1075
Reputation: 2058
The best way to stop your thread is to send a shutdown message, create a shutdown
property, initialized with a boolean false value, then set it as a condition to run your server (in a while
loop, set while !shutdown:
) then once your server receives a shutdown request from the client you will modify the value of the shutdown property with true which will stop the while loop and then shutdown your thread.
Upvotes: 0
Reputation: 1
ZeroMQ is a very powerful set of tools for smart distributed applications with messaging and signalling features ready to be "just used" ( if one knows how - anyway, do not hesitate to follow the book ).
A1: First, you need to start design your code-units in a non-blocking, asynchronous mode, so that you can still keep control over your threaded code independently of any internal/external blockers. As a lesson No.1, one has to forget to use just the naked .recv()
and mentally switch into zmq.NOBLOCK
and/or loop-controlled .poll( nMSECs )
where necessary ( not all ZeroMQ wrappers have such a comfort the pyzmq
has, so do benefit from this bonus ).
A2: as a rule-of-thumb, one may use several additional SIG
and DIAG
messaging ZeroMQ
-patterns added to the core-logic of any threaded code-unit. This helps you both in testing and in ad-hoc changes in any kind of internal settings ( effectively adding a distributed CLI
interface to your code-unit is cool by-product thereof, isn't it? ) and/or termination of the thread.
A3:
Oh sure there is. Whenever one feels a REQ/REP
Formal Communication Pattern is the right one, check the book again and re-design the code so that it can survive REQ/REP
inability to get itself from de-synced distributed-FSA
-stepping once it has silently fallen into de-synced state. Many posts refer to this principal issue.
Epilogue: sharing ZeroMQ-socket instances in threads is strongly discouraged.
Upvotes: 2