Resources are always limited, if the program is running to operate on the same object, it may cause resource competition may also lead to confusion to read and write, this time need to introduce locks.
Locks provide a method:
1.Lock.acquire ([blocking]) # lock
2.Lock.release () # unlocking
3.threading.Lock () # load lock thread objects, is a basic lock object, only once in order to be able to get a lock, the other lock requests to wait after the lock is released
4.threading.RLock () multiple lock in the same thread can be used multiple times acquire. If you use RLock, then acquire and release must be paired,
called n times acquire lock requests, you must call the n-th release to release the lock objects in the thread
For example:
no lock:
1 import threading 2 import time 3 4 g_num = 0 5 6 7 def work1(num): 8 for i in range(num): 9 global g_num 10 g_num += 1 11 print("___in work1,g_num is %d" % g_num) 12 13 14 def work2(num): 15 for i in range(num): 16 global g_num 17 g_num += 1 18 print("___in work2,g_num is %d" % g_num) 19 20 21 t1 = threading.Thread(target=work1, args=(1000000,)) 22 t2 = threading.Thread(target=work2, args=(1000000,)) 23 t1.start() 24 t2.start() 25 26 time.sleep(3) 27 28 print("___g_num is %d" % g_num)
operation result:
1 ___in work1,g_num is 1194618 2 ___in work2,g_num is 1334899 3 ___g_num is 1334899
The introduction of lock:
. 1 Import Threading 2 Import Time . 3 . 4 # define a global variable . 5 g_num = 0 . 6 . 7 . 8 DEF WORK1 (NUM): . 9 Global g_num 10 for I in (NUM) Range: . 11 # between locking and unlocking mutex included the better the code 12 is mutex.acquire () 13 is g_num. 1 = + 14 mutex.release () 15 Print ( " ___in WORK1, g_num IS% D " % g_num) 16 . 17 18 is DEF WORK2 (NUM): . 19 Global g_num 20 is for I in (NUM) Range: 21 is mutex.acquire () 22 is g_num +. 1 = 23 is mutex.release () 24 Print ( " ___in WORK2, g_num IS% D " % g_num ) 25 26 is 27 # Create a mutex, default unlocked 28 the mutex = of threading.Lock () 29 30 31 is T1 of the threading.Thread = (target = WORK1, args = (1000000 ,)) 32 T2 = Threading. Thread (target = work2, args = (1000000,)) 33 t1.start() 34 t2.start() 35 36 time.sleep(3) 37 38 print("___g_num is %d" % g_num)
operation result:
1 ___in work1,g_num is 1945701 2 ___in work2,g_num is 2000000 3 ___g_num is 2000000
Wherein:
Lock of threading.Lock = () method may also be replaced by load lock lock = threading.RLock ()
If the above work1 read:
1 mutex.acquire() 2 global g_num 3 mutexk.acquire() 4 for i in range(num): 5 g_num += 1 6 mutex.release() 7 print("___in work1,g_num is %d" % g_num) 8 mutexk.release()
Then:
Lock = threading.Lock () to load the lock, has been in waiting, waiting for a lock
and lock = threading.RLock () function properly
lock () solutions to avoid deadlock:
1. The program is set up to try to avoid (the banker's algorithm)
2. Add timeout