1. Thread Creation
1 #Method 1: Pass the method to be executed as a parameter to Thread Construction methods 2 import threading 3 import time 4 5 def show(arg): 6 time.sleep(2) 7 print('thread' + str(arg)) 8 9 for i in range(10): 10 t = threading.Thread(target=show,args=(i,)) 11 time.sleep(2) 12 t.start() 13 14 #Method 2: From Thread Inherit and Override run() 15 class MyThread(threading.Thread): 16 def __init__(self,num): 17 threading.Thread.__init__(self) 18 self.num = num 19 20 def run(self)):#Define the function to run for each thread 21 print("running on number:%s" %self.num) 22 time.sleep(3) 23 24 25 if __name__ == '__main__': 26 t1 = MyThread(1) 27 t2 = MyThread(2) 28 t1.start() 29 time.sleep(3) 30 t2.start()
Notes:
Thread(group=None,target=None,name=None,args=(),kwargs={})
Group: Thread group, not yet implemented, prompted for library reference must be None
target: Method to execute
Name: Thread name
args/kwargs: To pass in method parameters, args and kwargs are actually two-choice parameters
#Instance Method
isAlive(): Returns whether the thread is running
get/setName(name): Gets/sets the thread name
is/setDaemon(bool): Gets/sets whether to daemon threads.Initial values inherit from the thread that created the thread and terminate when no non-daemon thread is still running
start(): Start the thread
join([timeout]): Blocks threads in the current context.
2. Python multithreading usage
1 import threading 2 from time import ctime,sleep 3 4 def music(func): 5 for i in range(2): 6 print("I was listening to %s. %s" %(func,ctime())) 7 sleep(1) 8 def move(func): 9 for i in range(2): 10 print("I was at the %s! %s" %(func,ctime())) 11 sleep(5) 12 13 threads = [] 14 t1 = threading.Thread(target=music,args=('Once Upon a Time',)) 15 threads.append(t1) 16 t2 = threading.Thread(target=move,args=('Transformers',)) 17 threads.append(t2) 18 19 if __name__ == '__main__': 20 for t in threads: 21 t.setDaemon(True) 22 t.start() 23 24 print("all over %s" %ctime())
Note:
threads = []
t1 = threading.Thread(target=music,args=('fairy town',))
threads.append(t1)
Create threads array, create thread t1, use threading.Thread() method, call music method target=music, args method passes music.Load the created thread T1 into the threads array.
Next, create thread t2 in the same way and load t2 into the threads array.
for t in threads:
t.setDaemon(True)
t.start()
Finally, the array is traversed through a for loop.(Array is loaded with t1 and t2 threads)
setDaemon()
setDaemon(True) declares a thread as a daemon thread and must be set before the start() method call. If it is not set as a daemon, the program will hang indefinitely.After the child thread starts, the parent thread continues to execute. When the parent thread finishes executing the last statement print "all over%s"%ctime(), it exits without waiting for the child thread, and the child thread ends at the same time.
SerDeamon (False) (default) foreground thread. The foreground thread is also in progress during the main thread execution. After the main thread has finished executing, the main thread stops waiting for the foreground thread to finish executing.
Run result:
I was listening to Once Upon a Time. Thu Jun 22 23:23:07 2017 I was at the Transformers! Thu Jun 22 23:23:07 2017 all over Thu Jun 22 23:23:07 2017
Subthreads (muisc, move) and main threads (print "all over%s"%ctime()) are started at the same time from the execution results, but they also terminate because the main thread finishes execution.(
Adjustment procedure:
1 if __name__ == '__main__': 2 for t in threads: 3 t.setDaemon(True) 4 t.start() 5 6 t.join() 7 8 print "all over %s" %ctime()
The join() method has been added to wait for the thread to terminate.Join() is used to block the parent thread of a child thread until it has finished running.
The join() method is located outside the for loop, which means that you must wait for both processes in the for loop to finish before executing the main process.
Run result:
1 ##################### Run Result ################################ 2 I was listening to fairy tale town. Thu Jun 22 23:34:22 2017 3 I was at the Transformers! Thu Jun 22 23:34:22 2017 4 I was listening to fairy tale town. Thu Jun 22 23:34:23 2017 5 I was at the Transformers! Thu Jun 22 23:34:27 2017 6 all over Thu Jun 22 23:34:32 2017
From the time of the result, we can see that each song waits for one second, movies wait for five seconds, but they are synchronized, the total time is five seconds
3. Thread Lock (LOCK,RLOCK)
Because threads are randomly scheduled and each thread may execute only n executions, dirty data may appear when multiple threads modify the same data at the same time, a thread lock occurs - allowing one thread to perform operations at a time.
Lock is the lowest level of synchronization instruction available.Lock is not owned by a specific thread when it is locked.Lock has two states - locked and unlocked, and two basic methods.
You can think of Lock as having a lock pool that puts a thread in the pool when a thread requests a lock until it gets a lock and exits the pool.Threads in the pool are in a synchronous blocked state in the state diagram.*
RLock is a synchronous instruction that can be requested multiple times by the same thread.RLock uses the concepts of Owned Threads and Recursive Hierarchy, and when locked, RLock is owned by a thread.Threads with RLocks can call acquire() again, and release() needs to be called the same number of times to release a lock.
You can think of RLock as containing a lock pool and a counter with an initial value of 0, each time acquire()/release() is called successfully, the counter will + 1/-1, and the lock will be unlocked at 0.
In short: Lock is global and Rlock is thread.
1, no locks used
1 import threading 2 import time 3 4 num = 0 5 6 def show(arg): 7 global num 8 time.sleep(1) 9 num +=1 10 print(num) 11 12 for i in range(10): 13 t = threading.Thread(target=show, args=(i,)) 14 t.start() 15 16 print('main thread stop')
Multiple runs can cause confusion.This is the ideal scenario for using locks.
2. Use locks
1 import threading 2 import time 3 4 num = 0 5 lock = threading.RLock() 6 7 # call acquire([timeout])When the thread is blocked, 8 # Until locked or until timeout Seconds later ( timeout Optional parameters). 9 # Returns whether a lock has been acquired. 10 def show(arg): 11 lock.acquire() 12 global num 13 time.sleep(1) 14 num +=1 15 print(num) 16 lock.release() 17 18 for i in range(10): 19 t = threading.Thread(target=show, args=(i,)) 20 t.start() 21 22 print('main thread stop')
With the lock, the numbers will be printed step by step without being confused by the congestion!
4. Semaphore
Mutual exclusion locks allow only one thread to change data at the same time, while Semaphore allows a certain number of threads to change data at the same time, such as all three pits in the toilet, which allows a maximum of three people to go to the toilet, and the people behind it can only wait for someone to come out before entering.
1 import threading, time 2 3 def run(n): 4 semaphore.acquire() 5 time.sleep(3) 6 print("run the thread: %s" % n) 7 semaphore.release() 8 9 if __name__ == '__main__': 10 num = 0 11 semaphore = threading.BoundedSemaphore(5) # Allow up to five threads to run simultaneously 12 for i in range(20): 13 t = threading.Thread(target=run, args=(i,)) 14 t.start()
5. Events
Events for Python threads are mainly used by the main thread to control the execution of other threads. Events provide three main methods: set, wait, clear
Mechanisms for event handling: A "Flag" is defined globally. If the "Flag" value is False, the program will block when it executes the event.wait method. If the "Flag" value is True, the event.wait method will not block anymore.
clear: Set Flag to False
set: set Flag to True
Communication between threads using threading.Event
threading.Event causes a thread to wait for notifications from other threads to pass this event to the thread object, which has a flag built in by default and has an initial value of False.
Once the thread enters the wait state through the wait() method until another thread calls the Event's set() method to set the built-in flag to True,
This Event notifies all waiting threads to resume running.
1 import threading 2 3 def do(event): 4 print('start') 5 event.wait() 6 print('end') 7 8 event_obj = threading.Event() 9 10 for i in range(10): 11 t = threading.Thread(target=do, args=(event_obj,)) 12 t.start() 13 14 event_obj.clear() #Continue blocking 15 16 inp = input('input:') 17 if inp == 'true': 18 event_obj.set() # awaken
6. Conditions
The so-called conditional variable, that is, this mechanism allows threads to access related data only after certain conditions are met!
It is done using the Condition class, and since it can also be used like a lock mechanism, it also has the acquire and release methods, and it also has the wait, notify, notifyAll methods
1 import threading 2 import time 3 4 # Product Class 5 class Goods: 6 def __init__(self): 7 self.count = 0 8 9 def add(self, num=1): 10 self.count += num 11 12 def sub(self): 13 if self.count >= 0: 14 self.count -= 1 15 16 def empty(self): 17 return self.count <= 0 18 19 # Producer 20 class Producer(threading.Thread): 21 def __init__(self, condition, goods, sleeptime=1): 22 threading.Thread.__init__(self) 23 self.cond = condition 24 self.goods = goods 25 self.sleeptime = sleeptime 26 27 def run(self): 28 cond = self.cond 29 goods = self.goods 30 while True: 31 # Lock resources 32 cond.acquire() 33 goods.add() 34 print("Product Quantity:", goods.count, "Producer Threads") 35 # Wake up all waiting threads -> It's really waking up the consumer process 36 cond.notifyAll() 37 # Unlock Resources 38 cond.release() 39 time.sleep(self.sleeptime) 40 41 42 # Consumer 43 class Consumer(threading.Thread): 44 def __init__(self, condition, goods, sleeptime=2): 45 threading.Thread.__init__(self) 46 self.cond = condition 47 self.goods = goods 48 self.sleeptime = sleeptime 49 50 def run(self): 51 cond = self.cond 52 goods = self.goods 53 54 while True: 55 time.sleep(self.sleeptime) 56 # Lock resources 57 cond.acquire() 58 # Allow threads to wait if no product exists 59 while goods.empty(): 60 cond.wait() 61 goods.sub() 62 print("Product Quantity:", goods.count, "Consumer Threads") 63 64 65 g = Goods() 66 c = threading.Condition() 67 pro = Producer(c, g) 68 pro.start() 69 con = Consumer(c, g) 70 con.start()
7. Timer
1 import threading 2 def SayHello(): 3 print("hello world!") 4 t=threading.Timer(3,SayHello) 5 t.start() 6 def other_func(): 7 print("let me running!") 8 t=threading.Timer(1,other_func) 9 t.start() 10 11 if __name__ == "__main__": 12 SayHello() 13 other_func()