python multithreaded learning memorandum

Posted by kathas on Sat, 29 Jun 2019 19:25:33 +0200

python provides threading and threading as two multithreaded modules. Threading is more advanced, and most blogs introduce it.

1.threading module

The threading module provides methods:
- threading.current_thread() - Returns an instance of the current thread
threading.Thread thread class
By default, a process starts a thread, the main thread, named MainThread. The main thread can create other sub-threads. The default name of the sub-threads is "Thread-i" i, which indicates the number of sub-threads.
(1) Create threads
There are two ways to create threads:
1) By inheriting the Thread class and rewriting the run function
2) Pass in the function to run through the constructor
Thread(group=None, target=None, name=None, args=(), kwargs={})
- group not implemented
- target is the method to be executed
- name is the thread name
- parameters of target method corresponding to args

import threading#Import module
import time
#Pass in the method to be executed through the target parameter
def actions(arg):
    time.sleep(1)
    print 'thread %s '%arg
for i in xrange(5):
    t=threading.Thread(target=actions,args=(i,))
    t.start()
#By inheriting the Thread class and overwriting the run function
class MyThread(threading.Thread):
    def __init__(self,arg):
        #Initialization functions of parent classes must be explicitly invoked
        super(MyThread,self).__init__()
        self.arg=arg
    def run(self):
        time.sleep(1)
        print 'thread %s'%self.arg
for i in xrange(5):
    t=MyThread(i)
    t.start()

2.Thread class

The method provided by the Thread class:
- start() - Start threads
- join() - Wait until the thread terminates
- getName() - Returns the thread name
- setName() - Set the thread name
- isAlive() - Returns whether the thread is running
- setDaemon() - Setting up daemons must be invoked before starting ().
Some mechanisms of threads in Python are different from C/C++: in C/C++, when the main thread ends, its sub-threads will be kill ed by the main thread by default. In python, when the main thread ends, it defaults to wait for the sub-thread to finish before the main thread exits.
(1) Set Daemon ()
By default setDaemon(False), the thread is a user thread. After the main thread has finished executing, it waits for all threads to finish executing, and then the program exits.
setDaemon(True), which sets threads as daemon threads (also known as background threads). After the main program is executed, the program exits regardless of whether the daemon thread is executed or not.
The following shows the function of setDeamon() in a program example

#SetDeamon () is not set, and setDeamon (False) defaults to False.
import threading
print 'thread %s is running'%threading.current_thread().name
def actions(arg):
    sleep(1)
    print 'thread %s is running\n'%threading.current_thread().name
    print 'thread %s \n'%arg
    sleep(1)
for i in xrange(5):
    t=threading.Thread(target=actions,args=(i,))
    t.start()
print 'thread %s is running'%threading.current_thread().name

Operation results

thread MainThread is running
thread MainThread is ended
thread Thread-1 is running
thread 0
thread Thread-5 is running
thread Thread-4 is running
thread Thread-3 is running
thread Thread-2 is running
thread 4
thread 3
thread 2
thread 1
#You can see that after the main thread MainThread ends, the other threads continue to execute. The program exits until all threads are executed

Set up setDaemon(True)

import threading
print 'thread %s is running'%threading.current_thread().name
def actions(arg):
    sleep(1)
    print 'thread %s is running\n'%threading.current_thread().name
    print 'thread %s \n'%arg
for i in xrange(5):
    t=threading.Thread(target=actions,args=(i,))
    t.setDaemon(True)
    t.start()
print 'thread %s is running'%threading.current_thread().name

Operation results

thread MainThread is running
thread MainThread is ended
#As can be seen, the daemon thread is set as the sub-thread, and the main thread exits the program directly after execution, regardless of the execution status of the daemon thread.

(2)join() blocks threads in the current context until the thread calling the method terminates or reaches timeout. If the main thread has set Daemon (True), it will still wait for the sub-thread to finish.

print 'thread %s is running'%threading.current_thread().name
def actions(arg):
    sleep(1)
    print 'thread %s is running\n'%threading.current_thread().name
    print 'thread %s \n'%arg
    sleep(1)
threads=[]
for i in xrange(5):
    t=threading.Thread(target=actions,args=(i,))
    t.setDaemon(True)
    threads.append(t)
for t in threads:
    t.start()
for t in threads:
    t.join()
print 'thread %s is ended'%threading.current_thread().name

Operation results

thread MainThread is running
thread Thread-3 is running
thread Thread-5 is running
thread Thread-4 is running
thread Thread-2 is running
thread Thread-1 is running
thread 2
thread 4
thread 3
thread 1
thread 0
thread MainThread is ended
#After setting join(), the main thread waits for all subthreads to complete execution or expire before it ends.

[The join() method allows a thread to wait for another thread to run, while the setDaemon() method allows the main thread to end without waiting for a sub-thread. Both join and setDaemon can change the order of running between threads.)
Reference Blog:

3. Thread synchronization

When multiple threads modify the same data item, locks are needed to ensure the correctness of the data. It is implemented by the Lock and Rlock classes of threading module.
Lock and Rlock classes
Both classes have acquire methods (acquiring locks) and release methods (releasing locks)
Lock - Only lock and unlock states, not repeat acquire
Rlock - can be acquired multiple times by the same thread, but acquire and release must appear in pairs

Topics: Python