1. Add Flag
fromThreadingImportThreadImportTimeg_num=0g_flag= 1deftest1 ():GlobalG_numGlobalG_flagifG_flag = = 1: forIinchRange (1000000): G_num+ = 1G_flag=0Print("---test1---g_num=%d"%g_num)deftest2 ():GlobalG_numGlobalG_flagifG_flag! = 1:#test2 judgment unsuccessful, directly execute the PRINT statement, how to let it continue to judge forIinchRange (1000000): G_num+ = 1Print("---test2---g_num=%d"%g_num) P1= Thread (target=test1) P1.start () P2= Thread (target=test2) P2.start ()Print("---g_num=%d---"%g_num)
2. Polling: never-ending flag judgment
fromThreadingImportThreadImportTimeg_num=0g_flag= 1deftest1 ():GlobalG_numGlobalG_flagifG_flag = = 1: forIinchRange (1000000): G_num+ = 1G_flag=0Print("---test1---g_num=%d"%g_num)deftest2 ():GlobalG_numGlobalG_flag# Polling whileTrue:ifG_flag! = 1: forIinchRange (1000000): G_num+ = 1 Break Print("---test2---g_num=%d"%g_num) P1= Thread (target=test1) P1.start ()#Time.sleep (3) #取消屏蔽之后 run the program again, the results will be different, why? P2= Thread (target=test2) P2.start ()Print("---g_num=%d---"%g_num)
3. Mutual exclusion Lock
Synchronous control is required when multiple threads modify a shared data at almost the same time
Thread synchronization ensures that multiple threads secure access to competing resources, and the simplest synchronization mechanism is to introduce mutexes.
A mutex introduces a state to a resource: locked/non-locked.
- The lock class is defined in the threading module, allowing for easy handling of locks:
# Create lock mutex = Threading. Lock ()# locked mutex.acquire ([blocking])# release mutex.release ()
Where the locking method acquire can have a blocking parameter.
- If blocking is set to true, the current thread is blocked until the lock is acquired (true by default if not specified)
- If the setting blocking is false, the current thread does not clog
1) Mutex Lock program
fromThreadingImportThread, LockImportTimeg_num=0deftest1 ():GlobalG_num#this thread and the test2 thread are all rushing to lock the locks, and if there are 1 of them locked successfully, then another #one side will block (wait) until the lock is unlocked.Mutex.acquire () forIinchRange (1000000): G_num+ = 1mutex.release ()#used to unlock the lock that the mutex points to, as long as the lock is unlocked, then all #The lock was locked, and the blocked thread was locked. Print("---test1---g_num=%d"%g_num)deftest2 ():Globalg_num Mutex.acquire () forIinchRange (1000000): G_num+ = 1mutex.release ()Print("---test2---g_num=%d"%g_num)#create a mutex that is not locked by defaultMutex =Lock () P1= Thread (target=test1) P1.start ()#Time.sleep (3) #取消屏蔽之后 run the program again, the results will be different, why? P2= Thread (target=test2) P2.start ()Print("---g_num=%d---"%g_num)
- Prevents multiple threads from executing concurrently, a piece of code that contains a lock can actually be executed in single-threaded mode, and the efficiency is greatly reduced.
4. Issues with mutexes
Notification mechanism: 2nd thread goes to sleep, waits for 1th execution to complete to notify 2nd thread, not polling mechanism
1) lock and place in for
fromThreadingImportThread, LockImportTimeg_num=0deftest1 ():GlobalG_num forIinchRange (1000000): Mutex.acquire () G_num+ = 1mutex.release ()Print("---test1---g_num=%d"%g_num)deftest2 ():GlobalG_num forIinchRange (1000000): Mutex.acquire () G_num+ = 1mutex.release ()Print("---test2---g_num=%d"%g_num) Mutex=Lock () P1= Thread (target=test1) P1.start () P2= Thread (target=test2) P2.start ()Print("---g_num=%d---"%g_num)
1. Each lock two threads to Rob 2. Each time the first thread releases the lock, two programs continue to lock.
Summarize
The benefits of locking:
- Ensures that a piece of critical code can be executed completely from one thread to the next
The disadvantages of the lock:
- Prevents multiple threads from executing concurrently, a piece of code that contains a lock can actually be executed in single-threaded mode, and the efficiency is greatly reduced.
- Because multiple locks can exist, different threads hold different locks and try to acquire locks held by each other, which can cause deadlocks
8 Troubleshooting Multi-threaded errors in shared data