Thread, multithreading:
-
Thread theory:
-
What is a thread?
Threads are the smallest unit that the operating system can schedule operations. It is included in the process and is the actual unit of operation in the process.
-
Processes are only used to centralize resources (processes are only a resource unit, or a collection of resources), and threads are the executing units on the cpu.
-
Open a process space in memory, copy all the resource data of the main process, and then call the thread to execute the code.
-
Processes are resource units and threads are execution units
-
-
Thread vs process:
-
Starting a process costs a lot more than opening a thread.
-
The speed at which threads are opened is very fast.
-
Threads and threads can share data, processes and processes need to use queues and other methods to achieve communication.
from threading import Thread x = 3 def task(): global x x = 10 if __name__ == '__main__': t1 = Thread(target=task) t1.start() t1.join() print(x) # The value of x is 10, so data can be shared in the thread.
Resource data in the same process is shared among multiple threads of the process.
-
-
Thread application:
Concurrency: A cup seems to perform multiple tasks simultaneously
-
There are two ways to open a thread:
from threading import Thread # Modules for Importing Threads import time import random def task(name): print(f'{name} is running') time.sleep(random.random()) print(f'{name} is gone') if __name__ == '__main__': t = Thread(target=task,args=('Zhou Daolong',)) t.start() # Open threads print('----main')
from threading import Thread import time import random class MyThread(Thread): # Define a class, inherit the Thread class, and execute some of its methods def __init__(self,name): super().__init__() self.name = name def run(self): # There must be a run method print(f'{self.name} is running') time.sleep(random.random()) print(f'{self.name} is gone') if __name__ == '__main__': t = MyThread('Zhou Daolong') t.start() print('----main')
Its essence is to reconstruct the run method in Thread class
-
Other methods related to threads:
isAlive() - - Judging whether a thread is alive or not
getName() - - Gets the thread name
setName (Thread Name) - - Add Thread Name
Name - - - Gets the thread name
threading method:
CurrentThread () - - Gets the object of the current thread (you need to import the currentThread package)
import threading import time def run(arg): print(f'running sub thread:{threading.currentThread()}') threading.currentThread().name = 'task1' print(f'sub1 Thread...{threading.currentThread().getName()}') print(f'sub2 Thread...{threading.currentThread().name}') time.sleep(2) if __name__ == '__main__': t1 = threading.Thread(target=run,args=('t1',)) t1.start() print(f'sub1 Thread...{threading.currentThread().getName()}') print(f'sub2 Thread...{threading.currentThread().name}') ''' running sub thread:<Thread(Thread-1, started 11788)> sub1 Thread...MainThread sub1 Thread...task1 sub2 Thread...MainThread sub2 Thread...task1 '''
enumerate() --------- Returns a list containing all threaded objects (need to import enumerate package)
ActeCount () - - counting the number of threads running
import threading import time def run(n): print(f'task{n}') time.sleep(1) for i in range(3): t = threading.Thread(target=run,args=(i,)) t.start() time.sleep(1) print(threading.activeCount())
-
join and daemon thread
join: blocking, telling the main thread to wait for the sub-thread to finish executing before executing the main thread
from threading import Thread import time def task(name): print(f'{name} is running') time.sleep(1) print(f'{name} is gone') if __name__ == '__main__': start_time = time.time() t1 = Thread(target=task,args=('Little ape',)) t2 = Thread(target=task,args=('Little ape',)) t3 = Thread(target=task,args=('Little ape',)) t1.start() t1.join() t2.start() t2.join() t3.start() t3.join() print(time.time()-start_time)
Daemon threads:
from threading import Thread import time def task(): print(123) time.sleep(2) print(789) if __name__ == '__main__': t = Thread(target=task) t.daemon = True t.start() print(456) # Threads start very fast, so they execute task s first, and output 123. # Result: 123 456
Be careful:
from threading import Thread import time def foo(): print(123) time.sleep(3) print('end123') def bar(): print(456) time.sleep(3) print('end456') t1=Thread(target=foo) t2=Thread(target=foo) t1.daemon = True t1.start() t2.start() print('main-----') #Result: 123 123 main----- end123 end123
-
Mutex Lock
Because threads are randomly scheduled, when they modify one data at the same time, they generate dirty data, so there will be locks, so that only one thread can operate on the same data at the same time.
Thread lock:
import threading def run(): global num num += 1 # Can produce data insecurity num = 0 t_obj = [] for i in range(50): t = threading.Thread(target=run) t.start() t_obj.append(t) for i in t_obj: i.join() # Let each execution be random in sequence print(num)
Mutex:
from threading import Thread from threading import Lock x = 100 def task(lock): lock.acquire() global x tem = x x = tem - 1 lock.release() if __name__ == '__main__': mutex = Lock() for i in range(100): t = Thread(target=task,args=(mutex,)) t .start() print(x)
with: Automatic acquisition and release of locks in threads, etc.
So the code above can be written as follows:
from threading import Thread,Lock x = 100 def task(lock): with lock: global x tem = x x = tem - 1 mutex = Lock() for i in range(100): t = Thread(target=task,args=(mutex,)) t.start() print(x)