Use of threading Module for Python Multithreading

  • 2021-10-27 08:03:02
  • OfStack

Directory Introduction
Create Thread
Constructor mode
Inheritance mode
Guardian thread
Thread local data
Timer

Brief introduction

Python provides multithreading support through _ thread and threading modules. threading module combines the existing functions of _ thread module, and extends some new functions, with 10-point rich thread operation functions

Create Thread

There are usually two ways to create threads using threading modules:

1) Using the constructor of the Thread class in the threading module to create a thread, that is, directly instantiating the class threading. Thread, and calling the start method of the instantiated object to create a thread;

2) Inherit Thread class in threading module to create thread class, that is, derive a new subclass with threading. Thread, instantiate the new class, and call its start method to create thread.

Constructor mode

Call the following constructor of the threading. Thread class to create the thread:


threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

group Specifies the thread group to which this thread belongs. This parameter has not been implemented yet. For future extension  ThreadGroup  Class implementation is preserved. 
target Used for  run()  The callable object called by the method, the default is  None That means no method needs to be called. 
args Is the argument tuple used to call the target function, and the default is  () . 
kwargs Is the keyword parameter dictionary used to call the target function, and the default is  {} . 
daemon : If  daemon  No  None The thread will be explicitly set to daemon mode, regardless of whether the thread is in daemon mode, and if so  None ( Default value ) The thread inherits the daemon mode property of the current thread. 

import time
import threading

def work(num):
    print(' Thread name: ',threading.current_thread().getName(),' Parameters: ',num,' Start time: ',time.strftime('%Y-%m-%d %H:%M:%S'))

if __name__ == '__main__':
    print(' Main thread start time: ',time.strftime('%Y-%m-%d %H:%M:%S'))
    
    t1 = threading.Thread(target=work,args=(3,))
    t2 = threading.Thread(target=work,args=(2,))
    t3 = threading.Thread(target=work,args=(1,))
    
    t1.start()
    t2.start()
    t3.start()
    
    t1.join()
    t2.join()
    t3.join()
    
    print(' Main thread end time: ', time.strftime('%Y-%m-%d %H:%M:%S'))

The above example instantiates three instances of the Thread class and passes different parameters to the task function, start Method to open the thread, join Method blocks the main thread and waits for the current thread to finish running.

Inheritance mode

Creating a thread through inheritance involves the following steps: 1) defining a subclass of the Thread class and overriding the run method of the class; 2) Creating an instance of the Thread subclass, i.e. creating a thread object; And 3) invoking the start method of the thread object to start the thread. Examples are as follows:


import time
import threading

class MyThread(threading.Thread):
    
    def __init__(self,num):
        super().__init__()
        self.num = num
    
    def run(self):
        print(' Thread name: ', threading.current_thread().getName(), ' Parameters: ', self.num, ' Start time: ', time.strftime('%Y-%m-%d %H:%M:%S'))

if __name__ == '__main__':
   
     print(' Main thread start time: ',time.strftime('%Y-%m-%d %H:%M:%S'))
    
    t1 = MyThread(3)
    t2 = MyThread(2)
    t3 = MyThread(1)
   
     t1.start()
    t2.start()
    t3.start()
    
    t1.join()
    t2.join()
    t3.join()
    
    print(' Main thread end time: ', time.strftime('%Y-%m-%d %H:%M:%S'))

In the above example, the thread class MyThread is customized, inherits threading. Thread, and overrides the __init__ and run methods.

Guardian thread

A daemon thread (also known as a background thread) runs in the background, and its task is to provide services for other threads. For example, the garbage collection thread of Python interpreter is a daemon thread. If all foreground threads die, the daemon thread will die automatically. Take an example:


#  Do not set a daemon thread 
import threading

def work(num):
    for i in range(num):
        print(threading.current_thread().name + "  " + str(i))

t = threading.Thread(target=work, args=(10,), name=' Guardian thread ')
t.start()

for i in range(10):
    pass

#  Set the daemon thread 
import threading

def work(num):
    for i in range(num):
        print(threading.current_thread().name + "  " + str(i))

t = threading.Thread(target=work, args=(10,), name=' Guardian thread ')
t.daemon = True
t.start()

for i in range(10):
    pass

The above example intuitively shows that when the current platform thread ends, the daemon thread will automatically end.

If you set a thread as a daemon thread, it means that this thread is not important. When the process exits, you don't have to wait for this thread to exit; If your main thread does not have to wait for which child threads to complete when exiting, set these threads as daemon threads; If you want to wait for the child thread to finish before exiting, do nothing, or explicitly set the daemon property to false.

Thread local data

threading module of Python provides local method, which returns a global object. Different threads use the data stored in this object, while other threads are invisible (essentially, different threads create an independent dictionary for this object when using it). Take an example:


#  Do not use  threading.local
import threading
import time

num = 0

def work():
    global num
    
    for i in range(10):
        num += 1
        
    print(threading.current_thread().getName(), num)
    time.sleep(0.0001)
    
for i in range(5):
    threading.Thread(target=work).start()

In the above example, num is a global variable and becomes a public resource. Through the output results, we find that the calculation results between sub-threads interfere with each other.


#  Use  threading.local
num = threading.local()

def work():
    num.x = 0
    
    for i in range(10):
        num.x += 1
    
    print(threading.current_thread().getName(), num.x)
    time.sleep(0.0001)

for i in range(5):
    threading.Thread(target=work).start()

In the example using threading. local, num is a global variable, but the attribute num. x defined by each thread is unique to its own thread and is invisible to other threads, so the evaluation results of each thread do not interfere with each other.

Timer

threading module provides Timer class to realize timer function. Let's take an example:


#  Single execution 
from threading import Timer

def work():
    print("Hello Python")
    
# 5  Execute in seconds  work  Method 
t = Timer(5, work)
t.start()

Timer can only control the function to be executed once in the specified time. If we need to execute it repeatedly, we need to schedule it again. If we want to cancel the schedule, we can use cancel method of Timer. Take an example:


#  Repeated execution 
count = 0

def work():
    print(' Current time: ', time.strftime('%Y-%m-%d %H:%M:%S'))
    global t, count
    count += 1
    #  If  count  Less than  5 , start to go down 1 Secondary scheduling 
    if count < 5:
        t = Timer(1, work)
        t.start()

#  Specify  2  Execute in seconds  work  Method 
t = Timer(2, work)
t.start()

The above is the Python multithreading threading module of the use of the details, more information about the use of python threading please pay attention to other related articles on this site!


Related articles: