1 基本概述
采用threading.Lock()对象创建锁lock,即 lock = threading.Lock()
其相关方法主要有
lock.acquire() # lock the lock, possibly blocking until it can be obtained lock.release() # unlock of the lock lock.locked() # test whether the lock is currently locked
Lock(指令锁)是可用的最低级的同步指令;Lock处于锁定状态时,不被特定的线程拥有。
2 示例1
2.1 异常分析
import threading import time a = b =0 def value(): while True: if a != b : print("a = %d,b =%d"%(a,b)) t=threading.Thread(target=value) t.start() while True: a += 1 b += 1 t.join()
运行结果为一串数字
... a = 3361552,b =3361551 a = 3361552,b =3361551 a = 3361552,b =3361551 a = 3361552,b =3361551 a = 3361552,b =3361551 ...
说明:
(1)按照程序分析来讲,应该没有输出,
(2)打印出好多相同的数字
可能原因
(1)首先明确a b为全局变量,所以当全局变量a b的值发生变化时,进程中的a b值也会随之变化
(2)当主线程中while True 使的a b均+1 时,线程函数中的a b值也会发生变化;但是主线程中的a b值赋值过程有时间间隔, 而线程中没有阻塞函数,所以在a b赋值中间的一个时刻,存在有a != b 这个过程,满足了线程函数的打印条件;所以会有数值打印出来
(3)在运行过程中,CPU高达100%,此时while 赋值运行和线程函数的运行并不是完全一致的,所以出现了数值较大的波动,有的数值仅出现一次或几次,有的数值甚至出现几十次。
(4)会出现当a赋值,当b没有赋值的间隙,子线程执行打印到桌面
2.2 添加sleep时间
import threading import time a = b =0 def value(): while True: if a != b : print("a = %d,b =%d"%(a,b)) t=threading.Thread(target=value) t.start() while True: time.sleep(1) #添加sleep(1)时间 a += 1 b += 1 t.join()
运行
a = 3,b =3 a = 6,b =6 a = 15,b =15 a = 16,b =16 a = 17,b =17 a = 18,b =18 a = 19,b =19 a = 20,b =20
说明:
(1)打印出的数据之间的间隔不是“等差”关系
(2)运行过程可能是,
(a)a+1 赋值后,b尚未赋值,中间时间内线程判定出 a != b 为 True
(b)在print打印前,b+1赋值已经完成,而sleep(1)后,循环赋值中的a+1被阻塞;
(c)所以此时打印出的 a b值想等。
(3)为了说明 2 的过程,在b += 1 前添加 sleep(1),则打印出a的值比b的值均大1;且a b相同值行数达上百行。
(4)从 2 和 3 过程可以说明线
2.3 颠倒交换
import threading import time a = b =0 def value(): while True: # 不添加global关键词, # 则会 UnboundLocalError : local variable 'a' referenced before assignment # 也即在赋值前没有定义局部变量 a b global a global b a += 1 b += 1 t=threading.Thread(target=value) t.start() while True: if a != b: print("a = %d,b =%d" % (a, b)) t.join()
说明:
该出a b本是全局变量,而当不添加关键字global时则会出现未定义局部变量的报错。——暂时还没有搞懂为什么!
3 示例2
使用进程锁Lock
import threading a = b =0 # 创建线程锁对象 lock = threading.Lock() def value(): while True: lock.acquire() if a != b : print("a = %d,b =%d"%(a,b)) lock.release() t=threading.Thread(target=value) t.start() while True: lock.acquire() a += 1 b += 1 lock.release() t.join()
运行,文件一直没有打印出内容
说明
(1)在a b 赋值时加锁,另外一个再加锁,这时候才会阻塞,此时不会打印。
(2)不管是子线程中的while循环 ,还是主线程中的while循环,任意一个去掉 lock.acquire lock.release 后,均不会出现阻塞。均会打印输出内容。