线程锁(Python)
一、多个线程对同一个数据进行修改
from threading import Thread,Lock n = 0 def add(lock): for i in range(500000): global n with lock: n += 1 def sub(lock): for i in range(500000): global n with lock: n -= 1 t_l = [] lock = Lock() for i in range(2): t1 = Thread(target=add,args=(lock,)) t1.start() t2 = Thread(target=sub,args=(lock,)) t2.start() t_l.append(t1) t_l.append(t2) for t in t_l: t.join() print(n)
二、多个线程对同一列表进行操作
from threading import Thread,Lock import time n = [] def append(): for i in range(500000): n.append(1) def pop(lock): for i in range(500000): with lock: if not n: time.sleep(0.0000001) # 强制CPU轮转 n.pop() t_l = [] lock = Lock() for i in range(20): t1 = Thread(target=append) t1.start() t2 = Thread(target=pop,args=(lock,)) t2.start() t_l.append(t1) t_l.append(t2) for t in t_l: t.join() print(n)
三、单例模式创建对象加锁
import time class A: from threading import Lock __instance = None lock = Lock() def __new__(cls, *args, **kwargs): with cls.lock: if not cls.__instance: time.sleep(0.000001) # cpu轮转 cls.__instance = super().__new__(cls) return cls.__instance def func(): a = A() print(a) from threading import Thread for i in range(10): Thread(target=func).start()
拓展
#拓展知识(将函数执行过程的底层指令打印出来) import dis a = 0 def func(): global a a += 1 print(dis.dis(func)) ''' 锁 0 LOAD_GLOBAL 2 LOAD_CONST 4 INPLACE_ADD # GIL锁切换了 6 STORE_GLOBAL 释放锁 '''
总结
1:不要操作全局变量,不要在类里操作静态变量 2:+= -= *= /= if while 数据不安全 3:queue logging 数据安全的