from threading import Thread, Lock
import time
g_num = 0
def test1():
global g_num
for i in range(1000000):
mutex_flag = mutex.acquire(True) # 如果此句放入for外面就完全算是单线程执行了
# True表示堵塞,即如果这个锁在上锁前已被其他线程上锁,那么当前线程会一直卡在这里等待
# False表示非堵塞,即不管本次调用能否成功上锁,都不会卡在这里,而是继续向下执行
if mutex_flag:
g_num += 1
mutex.release()
print('in test1 g_num is %d' % g_num)
def test2():
global g_num
for i in range(1000000):
mutex_flag = mutex.acquire(True)
if mutex_flag:
g_num += 1
mutex.release()
print('in test2 g_num is %d' % g_num)
mutex = Lock()
t1 = Thread(target=test1)
t1.start()
t2 = Thread(target=test2)
t2.start()
print('g_num is %d' % g_num)
返回:
g_num is 118372
in test2 g_num is 1939130
in test1 g_num is 2000000
可见,加入互斥锁后结果符合预期
上锁解锁过程
当一个线程调用锁的acquire()方法获得锁时,锁就进入“locked”状态。
每次只有一个线程可以获得锁。如果此时另一个线程试图获得这个锁,该线程就会变为“blocked”状态,称为“阻塞”,直到拥有锁的线程调用锁的release()方法释放锁之后,锁进入“unlocked”状态。
线程调度程序从处于同步阻塞状态的线程中选择一个来获得锁,并使得该线程进入运行(running)状态。也就是说多线程时获得锁的线程不确定。
总结
锁的好处:
- 确保了某段关键代码只能由一个线程从头到尾完整地执行
锁的坏处:
- 阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了
- 由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁