GIL 全局解释器锁,python底层自带锁,每个线程在执行的过程中都需要先获取GIL,保证同一时刻只有一个线程在运行,目的是解决多线程同时竞争程序中的全局变量而出现的线程安全问题。
多线程共享数据量大(几百万)的时候,会有数据不安全
#多线程开发的时候共享全局变量会带来资源竞争效果,也就是数据不安全。
#如果想安全要引入线程锁
import threading x=1 def t1(num): global x for i in range(num): x+=1 print('T1............',x) def t2(num): global x for i in range(num): x+=1 print('T2%%%%%%%%%%%%',x) def m(): tt1=threading.Thread(target=t1,args=(1000000,)) tt2=threading.Thread(target=t2, args=(1000000,)) tt1.start() tt2.start()
#正确值 2000001
打印结果图
多线程操作全局变量,加锁,# 创建互斥锁,默认不上锁,只有一把锁
是否加等待时间没有关系
import threading import time locka=threading.Lock() x=1 def t1(num): global x print("t1",threading.currentThread().name) for i in range(num): locka.acquire() x+=1 time.sleep(0.01) locka.release() print('T1............',x) def t2(num): print("t2", threading.currentThread().name) global x for i in range(num): locka.acquire() time.sleep(0.02) x += 1 locka.release() print('T2%%%%%%%%%%%%',x) def m(): print("主", threading.currentThread().name) tt1=threading.Thread(target=t1,args=(1000,)) tt2=threading.Thread(target=t2, args=(1000,)) tt1.start() # tt1.join() tt2.start() # tt2.join() # print("线程长度",length) while True: # print("1111111111111") threading.enumerate() 当前的线程 length = len(threading.enumerate()) # print("线程长度",length) 最后只有主线程,主线程为1 if length<=1: break print("最终的值",x)
打印结果
多线程操作类属性,加锁,# 创建互斥锁,默认不上锁,只有一把锁。是否加等待时间没有关系
import threading import time class A(object): locka = threading.Lock() x = 1 def __init__(self,num): self.num=num def t1(self,num): print("t1", threading.currentThread().name) for i in range(num): # self.locka.acquire() self.x += 1 time.sleep(0.01) # self.locka.release() print('T1............', self.x) def t2(self,num): print("t2", threading.currentThread().name) for i in range(num): # self.locka.acquire() time.sleep(0.02) self.x += 1 # self.locka.release() print('T2%%%%%%%%%%%%', self.x) def m(): print("主", threading.currentThread().name) tt1 = threading.Thread(target=A.t1, args=(A,10000,)) tt2 = threading.Thread(target=A.t2, args=(A,10000,)) tt1.start() tt1.join() tt2.start() tt2.join() # print("线程长度",length) while True: # print("1111111111111") threading.enumerate() 当前的线程 length = len(threading.enumerate()) # print("线程长度",length) 最后只有主线程,主线程为1 if length <= 1: break print("最终的值", A.x)
打印结果
1、启动线程
import threading def test1(): print("11111111111") if __name__ == '__main__': t1=threading.Thread(target=test1) t1.start()
2、多线程继承
#多线程继承 class Mythread(threading.Thread): def __init__(self,n):
#继承父类 super(Mythread, self).__init__() self.n = n def run(self): print("task类方法……", self.n) time.sleep(1) def main():
#开启3个线程 for i in range(3):
#实例化自己的类 t=Mythread(i) t.start()
3、守护线程
守护线程:设置一个线程为守护线程,就表示你在说这个线程是不重要的,你的主线程在退出的时候,不用等待那些子线程完成
情况1:#setDaemon(True) 在start前面设置守护线程,True,主线程结束,子线程就结束
情况2:#i.setDaemon(False) 或 不设置守护线程。主线程结束后,子线程不结束
#setDaemon(True) 在start前面设置守护线程,True,主线程结束,子线程就结束 def movie(func): for i in range(2): print("看电影",func,ctime()) sleep(1) def music(func): for i in range(2): print("听音乐",func,ctime()) sleep(2) threadlist=[] t1=threading.Thread(target=movie,args=('扫黑风暴',)) t2=threading.Thread(target=music,args=('碎银几两',)) threadlist.append(t1) threadlist.append(t2) def main(): for i in threadlist: i.setDaemon(True) i.start() print("主线程") if __name__ == '__main__': main()
#i.setDaemon(False) 或 不设置守护线程。主线程结束后,子线程不结束 def movie(func): for i in range(2): print("看电影",func,ctime()) sleep(1) def music(func): for i in range(2): print("听音乐",func,ctime()) sleep(2) threadlist=[] t1=threading.Thread(target=movie,args=('扫黑风暴',)) t2=threading.Thread(target=music,args=('碎银几两',)) threadlist.append(t1) threadlist.append(t2) def main(): for i in threadlist: i.setDaemon(False) i.start() print("主线程") if __name__ == '__main__': main()
4、join()的作用是,在子线程完成运行之前,这个子线程的父线程将一直被阻塞。
def movie(func): for i in range(2): print("看电影",func,ctime()) sleep(1) def music(func): for i in range(2): print("听音乐",func,ctime()) sleep(2) threadlist=[] t1=threading.Thread(target=movie,args=('扫黑风暴',)) t2=threading.Thread(target=music,args=('碎银几两',)) threadlist.append(t1) threadlist.append(t2) def main(): for i in threadlist: i.setDaemon(True) i.start() print("主线程start") for j in threadlist: i.join() print("主线程join") if __name__ == '__main__': main()
python死锁
在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源时,就会造成死锁。
#方法一死锁 import time import threading locka=threading.Lock() lockb=threading.Lock() def test1(): locka.acquire() print("threadA拿到A锁") time.sleep(1) lockb.acquire() print("threadA拿到B锁") locka.release() print("threadA释放B锁") lockb.release() print("threadA释放B锁") def test2(): lockb.acquire() print("threadB拿到B锁") time.sleep(1) locka.acquire() print("threadB拿到B锁") lockb.release() print("threadB释放B锁") locka.release() print("threadB释放a锁") if __name__ == '__main__': t1 = threading.Thread(target=test1) t2 = threading.Thread(target=test2) t1.start() t2.start()
#方法二 死锁
import threading,time locka=threading.Lock() lockb=threading.Lock() #多线程继承死锁 class Mythreada(threading.Thread): def run(self): if locka.acquire(): print(self.name+'获取了A锁') time.sleep(1) if lockb.acquire(): print(self.name + '获取了A锁,又获取B锁') lockb.release() print("释放B锁") locka.release() print("释放A锁") class Mythreadb(threading.Thread): def run(self): if lockb.acquire(): print(self.name+'获取了B锁') time.sleep(1) if locka.acquire(): print(self.name + '获取了B锁,又获取A锁') locka.release() print("释放A锁") lockb.release() print("释放A锁") def main(): ta=Mythreada() tb=Mythreadb() ta.start() tb.start() if __name__ == '__main__': main()