Communication between threads

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Bierny
    New Member
    • Feb 2007
    • 12

    #1

    Communication between threads

    Hi,
    I am writing a Python script that will start two threads: one thread shall start the client application and catch logs from it and the other thread shall catch logs from the server side.
    So the first thread knows when it shall stop since it has a set of actions to be performed and when all it's tasks are done it simply terminates.
    Now i would like the other thread to terminate itself as soon as the first thread is gone.

    I have solved this problem with global event, so now it looks like this:

    Code:
    if __name__ == '__main__':
    
        stopEvent = Event()
        
        client = Client()
        client.start()
    
        server = Server()
        server.start()
    and here is a part of code from the server thread

    Code:
         while not stopEvent.isSet():
                
                print self.connection.readOutput()
    At this moment it just prints the logs from the server to the screen.

    So this is my temporary solution. I would like to do it in other way. When the client thread is about to terminate it could send signal like "I am done." so the server thread would know when it should terminate.

    How can I do that?

    Thanks in advance!

    Best regards,
  • bartonc
    Recognized Expert Expert
    • Sep 2006
    • 6478

    #2
    Originally posted by Bierny
    Hi,
    I am writing a Python script that will start two threads: one thread shall start the client application and catch logs from it and the other thread shall catch logs from the server side.
    So the first thread knows when it shall stop since it has a set of actions to be performed and when all it's tasks are done it simply terminates.
    Now i would like the other thread to terminate itself as soon as the first thread is gone.

    I have solved this problem with global event, so now it looks like this:

    Code:
    if __name__ == '__main__':
    
        stopEvent = Event()
        
        client = Client()
        client.start()
    
        server = Server()
        server.start()
    and here is a part of code from the server thread

    Code:
         while not stopEvent.isSet():
                
                print self.connection.readOutput()
    At this moment it just prints the logs from the server to the screen.

    So this is my temporary solution. I would like to do it in other way. When the client thread is about to terminate it could send signal like "I am done." so the server thread would know when it should terminate.

    How can I do that?

    Thanks in advance!

    Best regards,
    You seem to be on the right track here. There is a very cool example in O'Reily's Python Cookbook that uses these calls, but first subclasses threading.Threa d.
    In the overridden run(), is the main loop of the thread. In that loop, self._stopevent .wait() is called to see if the thread has been signal to terminate.
    In the overridden join(), call self._stopevent .set() and then threading.Threa d.join()

    Comment

    • Bierny
      New Member
      • Feb 2007
      • 12

      #3
      Hi,
      I have found some examples that, i believe, worked as you described. But there is one difference (at least from my point of view but since I am new in this kind of programming, I might be wrong :-) ) that it is controlled from the same class. So there is a class that has to create for instance 10 connections to the server. Each connection is a separate thread. Since they all share the same code every thread has access to the self._stopEvent .
      In my case there is a client thread

      Code:
      client = Client()
      and a server thread

      Code:
      server = Server()
      Anyway I will look for the example you referred to.

      Thanks for the hint!

      Best regards,

      Comment

      • bartonc
        Recognized Expert Expert
        • Sep 2006
        • 6478

        #4
        Originally posted by Bierny
        Hi,
        I have found some examples that, i believe, worked as you described. But there is one difference (at least from my point of view but since I am new in this kind of programming, I might be wrong :-) ) that it is controlled from the same class. So there is a class that has to create for instance 10 connections to the server. Each connection is a separate thread. Since they all share the same code every thread has access to the self._stopEvent .

        Best regards,
        I think I see what your conception is, because this is an easily mistaken view.
        In reality, each instance of a class is a separate creation. Anything named self.xxxx belongs only to that instance. That incluced the code.

        Comment

        • Bierny
          New Member
          • Feb 2007
          • 12

          #5
          Originally posted by bartonc
          I think I see what your conception is, because this is an easily mistaken view.
          In reality, each instance of a class is a separate creation. Anything named self.xxxx belongs only to that instance. That incluced the code.
          Now I am lost ... but maybe we could try different approach. Please take a look at the following script:

          Code:
          #!/app/Python/2.4/bin/python
          
          import time
          from threading import Thread, Event
          
          ################################################################################
          # USER DEFINED CLASSES
          ################################################################################
          
          class Client(Thread):
              """
              This class counts from 0 upto 9.
              """
          
              def __init__(self):
                  """
                  Set the counter limit and sleep period
                  """
          
                  Thread.__init__(self)
                  
                  self.limit = 10
                  self.sleepPeriod = 1.0
          
              def run(self):
                  """
                  Start counting!
                  """
          
                  counter = 0
          
                  while counter < self.limit:
          
                      print "Client's counter: %s" % counter
                      counter += 1
                      time.sleep(self.sleepPeriod)
          
          #-------------------------------------------------------------------------------        
                  
          class Server(Thread):
              """
              This class counts from 0 upto 14.
              """
          
              def __init__(self):
                  """
                  Set the counter limit and sleep period
                  """
          
                  Thread.__init__(self)
                  
                  self.limit = 15
                  self.sleepPeriod = 1.0
          
              def run(self):
                  """
                  Start counting!
                  """
          
                  counter = 0
          
                  while counter < self.limit:
          
                      print "Server's counter: %s" % counter
                      counter += 1
                      time.sleep(self.sleepPeriod)
                  
          ################################################################################
          # MAIN PROGRAM
          ################################################################################
          
          if __name__ == '__main__':
               
              myClient = Client()
              myClient.start()
          
              myServer = Server()
              myServer.start()
          Here is a small request to you. How would you change this script so the Server thread ends when the Client thread is finished?

          Thanks in advance!

          Best regards,

          Comment

          • bartonc
            Recognized Expert Expert
            • Sep 2006
            • 6478

            #6
            Code:
            #!/app/Python/2.4/bin/python
            
            import time
            from threading import Thread, Event
            import threading
            
            ################################################################################
            # USER DEFINED CLASSES
            ################################################################################
            
            class Client(Thread):
                """
                This class counts from 0 upto 9.
                """
            
                def __init__(self):
                    """
                    Set the counter limit and sleep period
                    """
                    Thread.__init__(self)
                    self._stopevent = threading.Event()
            #        self.limit = 10
                    self._sleepPeriod = 1.0
            
                def run(self):
                    """
                    Start counting!
                    """
                    counter = 0
                    while not self.stopevent.isSet():
            
                        print "Client's counter: %s" % counter
                        counter += 1
            #            time.sleep(self.sleepPeriod)
                        self._stopevent.wait(self._sleepPeriod)
            
                def join(self, timeout=None):
                    """Stop thread and wait for it to end."""
                    self._stopevent.set()
                    Thread.join(self, timeout)
            
            #-------------------------------------------------------------------------------        
                    
            class Server(Thread):
                """
                This class counts from 0 upto 14.
                """
            
                def __init__(self):
                    """
                    Set the counter limit and sleep period
                    """
            
                    Thread.__init__(self)
                    
                    self.limit = 15
                    self.sleepPeriod = 1.0
            
                def run(self):
                    """
                    Start counting!
                    """
            
                    counter = 0
            
                    while counter < self.limit:
            
                        print "Server's counter: %s" % counter
                        counter += 1
                        time.sleep(self.sleepPeriod)
                    
            ################################################################################
            # MAIN PROGRAM
            ################################################################################
            
            if __name__ == '__main__':
                 
                myClient = Client()
                myClient.start()
            
            #    myServer = Server()
            #    myServer.start()
            # work this code into your server class
                time.sleep(5.0)
                myClient.join()

            Comment

            • Bierny
              New Member
              • Feb 2007
              • 12

              #7
              Ok, so this is the usual handling of a thread. The server thread should be a main thread so it has control over the client thread.
              I can see a design mistake since I con not have to separete threads (meaning without main thread).
              In that case I will rebuid the script so there is one main thread which controls the other one.

              Thanks for your help!

              Best regards,

              Comment

              • bartonc
                Recognized Expert Expert
                • Sep 2006
                • 6478

                #8
                Originally posted by Bierny
                Ok, so this is the usual handling of a thread. The server thread should be a main thread so it has control over the client thread.
                I can see a design mistake since I con not have to separete threads (meaning without main thread).
                In that case I will rebuid the script so there is one main thread which controls the other one.

                Thanks for your help!

                Best regards,
                Whether the server is the main thread or a spawned thread (which could kill itself with self._stopevent .set()), is no big deal. If it is a spawned thread, the main thread could just run off the end of the module or exit() and you should be left with only two threads. It's probably safer to do it the way that you have mentioned here.

                Comment

                Working...