Python multithreading-threading module

Daemon thread

The threading module supports daemon threads, and its working method is: daemon threads are generally a server waiting for clients to request services. If there is no client request, the daemon thread is idle. If a thread is set as a daemon thread, it means that this thread is not important, and there is no need to wait for the execution of this thread to complete when the process exits.
Set the thread as a daemon thread:

thread.daemon = True

Check the guardian status of the thread, just check this value.

The entire python program will exit after all non-daemon threads exit, that is, the daemon thread guarantees the normal operation of other non-daemon threads.

Create thread

Use Thread to create a thread (recommended to choose the first three):

  • Create an instance of Thread and pass it a function.
  • Create an instance of Thread and pass it a callable class instance.
  • Derive a subclass of Thread and create an instance of the subclass.

Create an instance of Thread and pass it a function

Code

import threading
from time import sleep,ctime

loops = [4,2]

def loop(nloop,nsec):
    print('start loop ',nloop,' at:',ctime())
    sleep(nsec)
    print('loop ',nloop,' done at:',ctime())

def main():
    print('starting at:',ctime())
    threads = []
    nloops = range(len(loops))

    for i in nloops:
        t = threading.Thread(target=loop,args=(i,loops[i])) # 实例化Thread
        # loop为目标函数名,args为目标函数参数
        threads.append(t)

    for i in nloops:    # 开始线程
        threads[i].start()

    for i in nloops:    # 等待所有
        threads[i].join()   # 线程完成

    print('all DONE at:',ctime())

if __name__ == "__main__":
    main()

Output

starting at: Thu Sep 10 16:18:48 2020
start loop  0  at: Thu Sep 10 16:18:48 2020
start loop  1  at: Thu Sep 10 16:18:48 2020
loop  1  done at: Thu Sep 10 16:18:50 2020
loop  0  done at: Thu Sep 10 16:18:52 2020
all DONE at: Thu Sep 10 16:18:52 2020

join()The method will wait for the thread to end, or if the timeout period is provided, the timeout period is reached. The join()method of use is clearer than the infinite loop waiting for the lock to be released (this kind of lock is also known as the reason for the spin lock).如果主线程还有其他事情要去做,而不是等待这些线程完成(例如其他处理或者等待新的客户端请求),就可以不调用join()。join()方法只有在你需要等待线程完成的时候才是有用的。

Create an instance of Thread and pass it a callable class instance

Code

import threading
from time import sleep,ctime

loops = [4,2]

class ThreadFunc(object):

    def __init__(self,func,args,name=''):
        self.name = name
        self.func = func
        self.args = args

    def __call__(self):
        self.func(*self.args)

def loop(nloop,nsec):
    print('start loop ',nloop,' at:',ctime())
    sleep(nsec)
    print('loop ',nloop,' done at:',ctime())

def main():
    print('starting at:',ctime())
    threads = []
    nloops = range(len(loops))

    for i in nloops:    # 创建所有线程
        t = threading.Thread(
            target=ThreadFunc(loop,(i,loops[i]),
            loop.__name__))
        threads.append(t)

    for i in nloops:    # 开始所有线程
        threads[i].start()

    for i in nloops:    # 等待完成
        threads[i].join()

    print('all DONE at:',ctime())

if __name__ == "__main__":
    main()

Output

starting at: Thu Sep 10 16:43:57 2020
start loop  0  at: Thu Sep 10 16:43:57 2020
start loop  1  at: Thu Sep 10 16:43:57 2020
loop  1  done at: Thu Sep 10 16:43:59 2020
loop  0  done at: Thu Sep 10 16:44:01 2020
all DONE at: Thu Sep 10 16:44:01 2020

When instantiating the Thread object, the callable class ThreadFunc is also instantiated. At the same time, this class saves the function parameter args, the function itself func, and the string name of the function name. When a new thread is created, the code of the Thread class will call the ThreadFunc object, and then call the __call__() method (the function of this method is similar to overloading the () operator in the class, so that the class instance object can be called like ordinary Like functions, it is used in the form of "object name ()"). `Since we already have the parameters to be used, there is no need to pass them to the Thread() constructor, just call them directly.

Derive a subclass of Thread and create an instance of the subclass

Code

import threading
from time import sleep,ctime

loops = (4,2)

class MyThread(threading.Thread):

    def __init__(self,func,args,name=''):
        threading.Thread.__init__(self)
        self.name = name
        self.func = func
        self.args = args

    def run(self):
        self.func(*self.args)

def loop(nloop,nsec):
    print('start loop ',nloop,' at:',ctime())
    sleep(nsec)
    print('loop ',nloop,' done at:',ctime())

def main():
    print('starting at:',ctime())
    threads = []
    nloops = range(len(loops))

    for i in nloops:
        t = MyThread(loop,(i,loops[i]),loop.__name__)
        threads.append(t)

    for i in nloops:
        threads[i].start()

    for i in nloops:
        threads[i].join()

    print('all DONE at:',ctime())

if __name__ == '__main__':
    main()

Output

starting at: Thu Sep 10 17:18:35 2020
start loop  0  at: Thu Sep 10 17:18:35 2020
start loop  1  at: Thu Sep 10 17:18:35 2020
loop  1  done at: Thu Sep 10 17:18:37 2020
loop  0  done at: Thu Sep 10 17:18:39 2020
all DONE at: Thu Sep 10 17:18:39 2020

Compared 创建Thread的实例,传给它一个可调用的类实例with the derived subclasses, there are two changes:

  1. The constructor of the MyThread subclass must first call the constructor of its base class;
  2. The previous special method __call__() must be written as run() in this subclass

Guess you like

Origin blog.csdn.net/XZ2585458279/article/details/108516586