Python Way (Fourth twelve) thread other methods related, join (), the difference between the Thread class start () and run () method, the daemon thread

A thread related to other methods

  
  Thread instance of an object method 
    # isAlive (): Returns the thread is active. 
    # GetName (): Returns the thread name. 
    # SetName (): Set the thread name. 
  threading module provides a number of methods: 
    # threading.currentThread (): Returns the current thread object. 
    # Threading.enumerate (): Returns a list of running threads. Refers to the thread starts running, before the end, it does not include a thread before starting and after termination. 
    # Threading.activeCount (): Returns the number of threads that are running, and len (threading.enumerate ()) have the same result. 
    # threading.main_thread () return to the main thread object 
    # threading.get_ident () Returns the current thread ID, non-zero integers

  

example

  

  Time Import 
  Import Threading 
  : DEF FUNC (Arg) 
      the time.sleep (1) 
      Get the current process object Print (Arg, threading.current_thread (), threading.get_ident ()) # threading.current_thread (), 
      # threading.get_ident () get the current thread number 
  for i in the Range (10): 
      . threading.Thread (target = FUNC, args = (i,)) Start () 
  Print ( "the number of threads statistics", threading.active_count ()) # statistics for the current thread number 
  threading.current_thread (). setName ( "main thread") # set the thread name 
  print (threading.current_thread (). isAlive ( )) # a thread is not active 
  print ( "current thread", threading.current_thread ()) 
  Print ( "get the name of the current thread", threading.current_thread (). getName ()) 
  Print ( "thread variable list", threading.enumerate ()) # display all of the current thread in the form of a list of variables

  

 

 

Second, the thread join ()

And join method process similar to the role, the role of the join method of the thread is blocked waiting for child thread ends, join method has one parameter is the timeout, that is, if the main thread waits for timeout, the child thread has not ended, the main thread is forced to end child thread .

But the python default parameters to create threads, regardless of whether the main thread is finished, will be waiting for child thread is finished with only exit, whether as the result of join. Process does not join () is executed in the main process after the exit, while the main thread is waiting for a child thread is finished with the only exit.

 

  
  Threading Import 
  Import Time 
  DEF FUNC (n-): 
      the time.sleep (2) 
      Print ( "S threads are%"% n-) 
      Global G 
      G = 0 
      Print (G) 
  IF the __name__ == '__main__': 
      G = 100 
      T_L = [] 
      for I in Range (. 5): 
          T = of the threading.Thread (target = FUNC, args = (I,)) 
          t.start () 
          t_l.append (T) 
      Print ( "number of threads 1-- statistics", threading.active_count ()) # statistics of the current number of threads, the result is 6,5 child threads, plus a main thread 
      for t in T_L: 
          t.join () 
      Print ( 'the end') 
      Print ( "the number of threads statistics 2 - ", threading.active_count ()) # statistics of the current number of threads, the result is 1, only one main thread

  

Three differences, Thread class start () and run () method

 

start()

  
  Threading Import 
  Import Time 
  DEF the Add (X, Y): 
      for _ in Range (. 5): _ # decompression sequence assignment, _ represents the elements do not concern 
          the time.sleep (0.5) 
          Print ( "X + Y = {}" .format (X + Y)) 
  class the MyThread (of the threading.Thread): 
      DEF start (Self): 
          Print ( 'start -----') 
          . Super () start () # call parent class start () and the run () method 
      DEF RUN (Self): 
          Print ( 'RUN -----') 
          . Super () run () # call parent class start () and run () method 
  t = MyThread (target the Add =, name = "the MyThread", args = (. 1, 2)) 
  t.start () 
  # t.run () 
  Print ( "=== ==== End")

  

Results of the:

  
  start-----
  run-----
  ====end===
  x+y=3
  x+y=3
  x+y=3
  x+y=3
  x+y=3

  

Analysis: As can be seen start () method will first run start () method, then run the run () method.

From simple to track down the source start () call process:

  
  . 1, DEF start (Self): 
          Print ( 'start -----') 
          . Super () start () # call parent class start () and run () method 
  2, def start (self): # start the parent class () 
      _start_new_thread (self._bootstrap, ()) 
      # execute _start_new_thread find _start_new_thread, find _thread.start_new_thread again, here is the pass 
      # Next get self._bootstrap value found def _bootstrap, by self._bootstrap_inner ( ), the final implementation self.run # () 
      .... 
  . 3, _start_new_thread = _thread.start_new_thread 
  . 4, DEF start_new_thread (function, args, kwargs = None): 
      Pass 
  . 5, DEF _bootstrap (Self): 
      self._bootstrap_inner () 
  6, DEF _bootstrap_inner (Self): 
      .... 
      the try:
   
   
   
   
          self.run () # final start () method calls the run () method 
      the except SystemExit: 
          Pass

  

 

 

run()

  
  Threading Import 
  Import Time 
  DEF the Add (X, Y): 
      for _ in Range (. 5): _ # decompression sequence assignment, _ represents the elements do not concern 
          the time.sleep (0.5) 
          Print ( "X + Y = {}" .format (X + Y)) 
  class the MyThread (of the threading.Thread): 
      DEF start (Self): 
          Print ( 'start -----') 
          . Super () start () # call parent class start () and the run () method 
      DEF RUN (Self): 
          Print ( 'RUN -----') 
          . Super () run () # call parent class start () and run () method 
  t = MyThread (target the Add =, name = "the MyThread", args = (. 1, 2)) 
  # t.start () 
  t.run () 
  Print ( "=== ==== End")

  

Results of the:

  
  run-----
  x+y=3
  x+y=3
  x+y=3
  x+y=3
  x+y=3
  ====end===

  

Analysis: run running thread () method can only be called to run () method.

From simple to track down the source runt () call process:

  
  . 1, DEF RUN (Self): 
      Print ( 'RUN -----') 
      . Super () run () # call parent class start () and run () method 
  2, def __init __ (self, group = None , target = None, name = None, 
                   args = (), kwargs = None, *, daemon = None): 
      self._target = # _target target here is the function name sub-thread 
      self._args = args 
      self._kwargs = kwargs 
      .... 
  3, DEF RUN (Self): 
      IF self._target: 
          self._target (self._args *, ** self._kwargs) # here to perform this function directly
   

  

Analysis: target is we pass the objective function, run () method is similar to a decorator in fact, eventually will args and kwargs argument to run the objective function, returns the result.

 

Continue to analyze:

start()

  Threading Import 
  Import Time 
  DEF FUNC (n-): 
      the time.sleep (2) 
      Print ( "S threads are%" n-%) 
      Print (. 'child thread ID number A', threading.current_thread () ident) 
      Global G 
      0 = G 
      Print ( 'child thread G', G) 
  class myThread (of the threading.Thread): 
      DEF the __init __ (Self, Arg, * args, ** kwargs): 
          Super () .__ the init __ (* args, kwargs **) 
          self.arg = Arg 
      DEF start (Self): 
          Print ( 'start -----') 
          . Super () start () # call parent class start () and run () method 
      def run (self): 
          Print ( 'run-----')
          print ( "class sub-thread", self.arg) 
          Super () RUN (). 
          Print ( 'child thread ID number B', threading.current_thread () ident.) 
  IF the __name__ == '__main__': 
      = 100 G 
      T1 = myThread ( 'Hello', target = FUNC, name = "the myThread", args = ( 'Nick',)) 
      # the first parameter is used in myThread class, three parameters used in the later func child thread created, args must be iterative 
      # func here can also be written directly in Mythread the run (), at which point run here () do not have to run to inherit the parent class () 
      t1.start ( ) 
      # t1.run () 
      Print ( 'main thread G', G) 
      Print ( 'ID number of the main thread ---', threading.current_thread (). ident )

  

Results of the

  
  ----- Start 
  RUN ----- 
  class child thread hello 
  thread is a nick 
  child thread ID number 19672 A 
  g 0 in the sub-thread 
  child thread ID number B 19672 
  main thread g 0 
  main thread ID No. 12056 ---

  

Analysis: Here you can see the main input Cheng Youzi thread func () and mythread.run () belonging to the same sub-thread, because mythread.run () inherits the parent class's run () will eventually have to execute func () function here just in the object write a few lines.

run()

  
  Threading Import 
  Import Time 
  DEF FUNC (n-): 
      the time.sleep (2) 
      Print ( "S threads are%" n-%) 
      Print (. 'child thread ID number A', threading.current_thread () ident) 
      Global G 
      0 = G 
      Print ( 'child thread G', G) 
  class myThread (of the threading.Thread): 
      DEF the __init __ (Self, Arg, * args, ** kwargs): 
          Super () .__ the init __ (* args, kwargs **) 
          self.arg = Arg 
      DEF start (Self): 
          Print ( 'start -----') 
          . Super () start () # call parent class start () and run () method 
      def run (self): 
          print ( 'run -----')
          print ( "class sub-thread", self.arg) 
          Super () RUN (). 
          Print ( 'child thread ID number B', threading.current_thread () ident.) 
  IF the __name__ == '__main__': 
      = 100 G 
      T1 = myThread ( 'Hello', target = FUNC, name = "the myThread", args = ( 'Nick',)) 
      # the first parameter is used in myThread class, three parameters used in the later func child thread created, args must be iterative 
      # func here can also be written directly in Mythread the run (), at which point run here () do not have to inherit the parent class run () 
      # t1.start () 
      t1.run () 
      Print ( 'main thread G', G) 
      Print ( 'ID number of the main thread ---', threading.current_thread (). ident )

  

Results of the

  
  RUN ----- 
  class child thread hello 
  thread is a nick 
  child thread ID number 18332 A 
  G 0 child thread 
  child thread ID number 18332 B 
  G 0 main thread 
  ID number of the primary thread --- 18332

  

Analysis: This can be seen, the program actually only has a thread, and that is the main thread.

 

example

  
  Import Threading 
  # define prepared as a sub-thread action function 
  DEF action (max): 
      for i in the Range (max): 
          When the # direct call to run () method, Thread name attribute returns the name of the object 
          # instead of the current thread name 
          # use threading.current_thread () name always get the current thread's name. 
          Print # ① (threading.current_thread () name + "" + str (i).) 
  for i in the Range (100): 
      # of calls thread currentThread () method to get the current thread 
      Print (threading.current_thread () name + "" + str (i).) 
      IF i == 20: 
          # thread object directly call run () method 
          # system will thread object as an ordinary object the run () method as an ordinary method 
          # following two lines of code, and therefore will not start two threads, but performed sequentially two run () method 
          threading.Thread (target = action, args = (100,)). run ( )
          threading.Thread (target = action, args = (100,)). run ( )

  

After the above procedure creates a thread object directly call the thread object's run () method, the result of running the entire program is only one main thread. Another point to be noted that, if the direct object the calling thread run () method, you can not directly obtain the name of the current thread of execution by the name attribute (getName () method) in the run () method, but requires the use of threading.current_thread () function to get the current thread, and then call the thread object's name property to get the name of the thread.

Not difficult to see through the above procedure, the right way to start the thread that calls start () method of the Thread object, instead of calling run () method, otherwise it becomes a single-threaded programs.

It should be noted that, in the calling thread object's run after () method, the thread was no longer in the new state, not the object of the calling thread again start () method.

 

Note that you can call start () method of the thread in the new state. In other words, if the procedure is repeated on the same thread calls start () method throws an exception RuntimeError.

 

to sum up:

From four small example above, we can conclude that:

  • start () method is to start a child thread

  • run () method does not start a new thread, it is to call a common function in the main thread only.

 

So, if you want to start multiple threads, you must use the start () method.

 

 

 

Fourth, the daemon thread

Daemon thread in the "after all non-daemon threads in the process are all finished running, a daemon thread will hang." After the main thread is not finished running daemon threads hang. This is the daemon and the differences will!

It is emphasized that: not finished running terminate **.

Whether it is a process or thread, follow: Guardian xxx xxx will wait after the run is completed destruction

 

Processes and threads daemon (line) Cheng contrast

  • The main process, the operation is completed refers to the main process code has finished running

  • The main thread, the run is completed refers to the main thread within a process where all non-daemon threads all finished running, the main thread is considered finished running

 

Daemon: the main process code has finished running, the daemon will be over (the guardian is the primary process)

                    Main and other non-daemon process to run is completed and then recycling the child process (or will cause a zombie process) until the end

                    Child process because the primary process and so is the main process to give the child to remove it (wait alternative method to initiate resource recovery signal to the operating system (pid, the state information))

 

Daemon thread: Non-threaded code has finished running daemon, daemon threads will be over (the guardian of non-daemon threads)

                     The main thread considered the end (the end means the end of the process the main thread, the thread will be the guardian of the recovery at this point) after the completion of other non-daemon threads running

                    He stressed: the main thread is a non-threaded daemon (process that contains the thread)

 

to sum up:

  1. The main thread alive, a daemon thread will survive. After the main thread, the thread is automatically killed the guardian end of the run.

  2. The main thread to wait after all non-daemon thread exits will quit if you want to end non-daemon thread, we have to manually identify non-daemon thread to kill.

Examples

The main thread starts two sub-thread:

  • Child thread 0- daemon thread, run for 10 seconds to exit

  • Sub-thread 1- non-daemon threads running one second exit.

According summarized above us, we will know:

  • The main thread finish promoter thread, wait for all non-daemon threads running

  • Non-daemon threads to run sub-11 seconds to exit

  • At this point there is no non-daemon threads running, the main thread exits

  • Although the child thread 0 task has not been completed, but it is a daemon thread exits followed by the main thread.

 

example

  
  # 守护线程
  from threading import Thread
  import time
  ​
  def func1():
      while True:
          print("in func1")
          time.sleep(5)
  ​
  def func2():
      print("in func2")
      time.sleep(1)
  ​
  t1 = Thread(target=func1,)
  t1.daemon = True
  t1.start()
  t2 = Thread(target=func2,)
  t2.start()
  print("主进程")

  

Analysis: The t1 thread as a daemon thread execution must be endless, because other non-daemon thread execution is over quickly, the main thread coming to an end, the main thread end of the process to recycle resources, so as t1 daemon thread will be terminated immediately out.

 

 

Example 2

  
  ​
  from threading import Thread
  import time
  def foo():
      print(123)
      time.sleep(1)
      print("end123")
  ​
  def bar():
      print(456)
      time.sleep(3)
      print("end456")
      
  t1=Thread(target=foo)
  t2=Thread(target=bar)
  ​
  t1.daemon=True
  t1.start()
  t2.start()
  print("主线程-------")

  

Analysis: Although set t1 is a daemon thread, but due to the short time t1 thread running, so here is a daemon thread will run to completion, running half the cases do not appear to exit the program.

 

 

Guess you like

Origin www.cnblogs.com/Nicholas0707/p/10930083.html