koci
koci

Reputation: 31

How to stop a thread that is waiting for Client to .connect()?

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

Answers (2)

Anas EL KORCHI
Anas EL KORCHI

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

user3666197
user3666197

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

Related Questions