title: Python threading.Thread can be stopped only with private method self.__Thread_stop()
body: <p>I have a function that accepts a large array of x,y pairs as an input which does some elaborate curve fitting using numpy and scipy and then returns a single value. To try and speed things up I am trying to have two threads that I feed the data to using Queue.Queue . Once the data is done. I am trying to have the threads terminate and then end the calling process and return control to the shell.</p>
  
  <p>I am trying to understand why I have to resort to a private method in threading.Thread to stop my threads and return control to the commandline.</p>
  
  <p>The self.join() does not end the program. The only way to get back control was to use the private stop method.</p>
  
  <pre><code>        def stop(self):
              print "STOP CALLED"
              self.finished.set()
              print "SET DONE"
              # self.join(timeout=None) does not work
              self._Thread__stop()
  </code></pre>
  
  <p>Here is an approximation of my code:</p>
  
  <pre><code>    class CalcThread(threading.Thread):
          def __init__(self,in_queue,out_queue,function):
              threading.Thread.__init__(self)
              self.in_queue = in_queue
              self.out_queue = out_queue
              self.function = function
              self.finished = threading.Event()
  
          def stop(self):
              print "STOP CALLED"
              self.finished.set()
              print "SET DONE"
              self._Thread__stop()
  
          def run(self):
              while not self.finished.isSet():
                  params_for_function = self.in_queue.get()
                  try:
                      tm = self.function(paramsforfunction)
                      self.in_queue.task_done()
                      self.out_queue.put(tm)
                  except ValueError as v:
                      #modify params and reinsert into queue
                      window = params_for_function["window"]
                      params_for_function["window"] = window + 1
                      self.in_queue.put(params_for_function)
  
      def big_calculation(well_id,window,data_arrays):
              # do some analysis to calculate tm
              return tm
  
      if __name__ == "__main__":
          NUM_THREADS = 2
          workers = []
          in_queue = Queue()
          out_queue = Queue()
  
          for i in range(NUM_THREADS):
              w = CalcThread(in_queue,out_queue,big_calculation)
              w.start()
              workers.append(w)
  
          if options.analyze_all:
                for i in well_ids:
                    in_queue.put(dict(well_id=i,window=10,data_arrays=my_data_dict))
  
          in_queue.join()
          print "ALL THREADS SEEM TO BE DONE"
          # gather data and report it from out_queue
          for i in well_ids:
              p = out_queue.get()
              print p
              out_queue.task_done()
              # I had to do this to get the out_queue to proceed
              if out_queue.qsize() == 0:
                  out_queue.join()
                  break
  # Calling this stop method does not seem to return control to the command line unless I use threading.Thread private method
  
          for aworker in workers:
              aworker.stop()
  </code></pre>