thread
The scheduling unit of CPU is simply the end executor in the program, which is equivalent to the position of younger brother.
Some people say that the thread in python is a chicken rib because of GIL, but it is not a chicken rib. After all, it works well when performing io operations, but it is unsatisfactory when performing calculations.
Let's see how to use threads:
1. Import thread module:
import threading as t
2. Thread usage
tt=t.Thread(group=None,target=None,name=None,args=(),kwargs={},name='',daemon=None) group:Thread group, must be None target:Running functions args:Parameter tuple of the incoming function kwargs:Parameter Dictionary of the incoming function name:Thread name daemon:Whether the thread exits with the main thread(Daemons) Thread The return value of the method also has the following methods: tt.start() : Activate thread, tt.getName() : Get the name of the thread tt.setName() : Set the name of the thread tt.name : Gets or sets the name of the thread tt.is_alive() : Judge whether the thread is active tt.isAlive() : Judge whether the thread is active tt.setDaemon() Set as daemons (default: False) tt.isDaemon() : Determine whether it is a guardian thread tt.ident : Gets the identifier of the thread. Only when called start()Method before the property is valid tt.join() : Execute each thread one by one, and continue to execute after execution tt.run() : Auto execute thread object t The methods are as follows: t.active_count(): Returns the number of running threads t.enumerate(): Returns the list of running threads t.current_thread().getName() Get the name of the current thread t.TIMEOUT_MAX set up t Global timeout for
Let's take a look at this:
3. Create thread
Threads can be created by Thread method, or can override the run method implementation of Thread class. Threads can be divided into single Thread and multi Thread.
Using the Thread method to create
1. Single thread
def xc(): for y in range(100): print('In operation'+str(y)) tt=t.Thread(target=xc,args=()) #Method join to thread tt.start() #Start thread tt.join() #Wait for child thread to end
2. Multithreading
def xc(num): print('function:'+str(num)) c=[] for y in range(100): tt=t.Thread(target=xc,args=(y,)) tt.start() #Start thread c.append(tt) #Create list and add thread for x in c: x.join() #Wait for child thread to end
Class method of rewriting thread
1. Single thread
class Xc(t.Thread): #Inherit Thread class def __init__(self): super(Xc, self).__init__() def run(self): #Override run method for y in range(100): print('In operation'+str(y)) x=Xc() x.start() #Start thread x.join() #Wait for child thread to end //It can also be written as follows: Xc().run() The effect is the same as above
2. Multithreading
class Xc(t.Thread): #Inherit Thread class def __init__(self): super(Xc, self).__init__() def run(self,num): #Override run method print('function:'+str(num)) x=Xc() for y in range(10): x.run(y) #function
Line lock
Why do you need to lock it? Look at this and you will know:
When multithreading accesses an object at the same time, it will occupy resources, so we have to tie it down, so we need to add a Lock to Lock it, which is a synchronous Lock. To unlock, we must first create a Lock. There are two types of locks in the thread: Lock and RLock.
1,Lock
usage method:
#Acquire lock When the lock cannot be acquired, it will enter the blocking state by default and set the timeout until the lock is acquired. Timeout disable setting when non blocking. If the timeout still fails to acquire the lock, return False. Lock.acquire(blocking=True,timeout=1) #Release the lock. The locked lock will be set to unlocked. If the call is unlocked, a RuntimeError exception is thrown. Lock.release()
Mutually exclusive lock, synchronous data, solve the security problem of multithreading:
n=10 lock=t.Lock() def xc(num): lock.acquire() print('function+: '+str(num+n)) print('function-: '+str(num-n)) lock.release() c=[] for y in range(10): tt=t.Thread(target=xc,args=(y,)) tt.start() c.append(tt) for x in c: x.join()
In this way, it seems to be organized, and the output is first + then -. Lock using the same resource multiple times in a thread can cause a deadlock.
Deadlock problem:
n=10 lock1=t.Lock() lock2=t.Lock() def xc(num): lock1.acquire() print('function+: '+str(num+n)) lock2.acquire() print('function-: '+str(num-n)) lock2.release() lock1.release() c=[] for y in range(10): tt=t.Thread(target=xc,args=(y,)) tt.start() c.append(tt) for x in c: x.join()
2,RLock
Compared with Lock, it can be recursive, supports multiple requests for the same resource in the same thread, and allows multiple locks in the same thread, but acquire and release must appear in pairs.
Use recursive locks to resolve deadlocks:
n=10 lock1=t.RLock() lock2=t.RLock() def xc(num): lock1.acquire() print('function+: '+str(num+n)) lock2.acquire() print('function-: '+str(num-n)) lock2.release() lock1.release() c=[] for y in range(10): tt=t.Thread(target=xc,args=(y,)) tt.start() c.append(tt) for x in c: x.join()
At this time, the output variable becomes just one, and does not grab resources at will. For thread locks, with can also be used more easily:
#with context management, lock object supports context management with lock: #with means to open the automatic release lock automatically for i in range(10): #No one else can work during lock up print(i) #The top and the bottom are equivalent if lock.acquire(1):#Lock success and continue to work. Wait until you lock success. 1 means exclusive for i in range(10): #Other threads cannot work during lock print(i) lock.release() #Release lock
3. Conditional lock
Wait to pass. Condition(lock=None) can be passed in lock or Rlock. The default Rlock is used as follows:
Condition.acquire(*args) acquire lock Condition.wait(timeout=None) wait for notification, timeout set timeout Condition.notify(num) wakes up at most a specified number of waiting threads, without which there is no operation Condition.notify_all() wakes up all waiting threads or notifyAll()
def ww(c): with c: print('init') c.wait(timeout=5) #Set wait timeout 5 print('end') def xx(c): with c: print('nono') c.notifyAll() #Wake all threads print('start') c.notify(1) #Wake up a thread print('21') c=t.Condition() #Create conditions t.Thread(target=ww,args=(c,)).start() t.Thread(target=xx,args=(c,)).start()
In this way, you can wake up other threads existing in other functions in the wake-up function while waiting.
Semaphore
Semaphores can be divided into bounded semaphores and unsolved semaphores. Let's see their usage specifically:
1. Bounded semaphore
It does not allow release to be used outside the range of the initial value, otherwise, a ValueError exception is thrown.
#Construction method. value is the initial semaphore. value is less than 0, throw ValueError exception b=t.BoundedSemaphore(value=1) #When the semaphore is acquired, the counter is decremented by 1, i.e_ The value of value is reduced by 1. If_ A value of 0 becomes blocked. Get success return True BoundedSemaphore.acquire(blocking=True,timeout=None) #Release semaphore, counter plus 1. I.e_ Add 1 to the value of value. If the value exceeds the initialization value, an exception ValueError will be thrown. BoundedSemaphore.release() #Semaphore, current semaphore BoundedSemaphore._value
You can see that there are multiple release s and an error is reported.
2. Unbounded semaphore
It does not check the upper limit of the release, but simply adds and subtracts the counter.
It can be seen that although there are more release s, there is no problem, and the number of semaphores is unlimited.
Event
For inter thread communication, the operation is performed by False or True of the flag set by the thread. The common methods are as follows:
event.set () flag set to True event.clear () flag set to False event.is_ Whether set() flag is True, if event.isSet()==False will block the thread; Set the waiting time when flag is True and None is infinite. Wait until return to True, and return to False before timeout event.wait(timeout=None)
Here is an example:
import time e=t.Event() def ff(num): while True: if num<5: e.clear() #Clear signal sign print('empty') if num>=5: e.wait(timeout=1) #Wait signal is true e.set() print('start-up') if e.isSet(): #Clear flag if signal flag is true e.clear() print('stop it') if num==10: e.wait(timeout=3) e.clear() print('sign out') break num+=1 time.sleep(2) ff(1)
After setting the delay, you can see that the effect is quite obvious. We can do whatever we want him to do.
local
Each thread can be created to belong to its own variables (thread local variables), and their values are in the form of dictionaries in the thread that currently calls it.
Let's look at:
l=t.local() #Create a thread local variable def ff(num): l.x=100 #Set the value of the x method of the l variable to 100 for y in range(num): l.x+=3 #change a value print(str(l.x)) for y in range(10): t.Thread(target=ff,args=(y,)).start() #Start execution thread
So, can the x method of a variable be set as a global variable? Let's look at:
It can be seen that he reported an error. The reason for the error is that there is no attribute x in this class. We can simply understand that local variables only accept local variables.
Timer
Set a timing plan to execute a method repeatedly within a specified time. His method of use is:
t.Timer(num,func,*args,**kwargs) #Restart the program again within the specified time
Let's look at:
def f(): print('start') global t #Prevent thread piling up and final program exit tt= t.Timer(3, f) tt.start() f()
In this way, the f function is executed every three seconds.
Through a comprehensive analysis of threads, we have learned the importance of threads, which can simplify our complex problems. It's quite useful for those who like to play reptiles. This article basically covers all the concepts of threads, hoping to help you.
Source network, for learning purposes only, invasion and deletion.
Don't panic. I have a set of learning materials, including 40 + E-books, 800 + teaching videos, involving Python foundation, reptile, framework, data analysis, machine learning, etc. I'm not afraid you won't learn! https://shimo.im/docs/JWCghr8prjCVCxxK/ Python learning materials
Pay attention to the official account [Python circle].