- 同步锁
给一段代码加了同步锁之后,在这段代码执行时只能有一个线程执行。
import time
import threading
def addNum():
global num #在每个线程中都获取这个全局变量
#num-=1
temp=num
#print('--get num:',num )
time.sleep(0.1)#可以把时间调短一点,看看是什么效果
num =temp-1 #对此公共变量进行-1操作
num = 100 #设定一个共享变量
thread_list = []
for i in range(100):
t = threading.Thread(target=addNum)
t.start()
thread_list.append(t)
for t in thread_list: #等待所有线程执行完毕
t.join()
print('final num:', num )#结果为99,多个线程都在同时操作同一个共享资源,所以造成了资源破坏
加锁后
import time
import threading
R = threading.Lock()
####
def sub():
global num
R.acquire() #
temp = num - 1 #
time.sleep(0.1) #
num = temp #这五行相当于串行,但如果后面还有代码就会是并发的
R.release() #
num=100
thread_list = []
for i in range(100):
t = threading.Thread(target=sub)
t.start()
thread_list.append(t)
for t in thread_list: #等待所有线程执行完毕
t.join()
print('final num:', num )#结果是0
- 死锁
在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁,因为系统判断这部分资源都正在使用,所有这两个线程在无外力作用下将一直等待下去。例子:
import threading,time
class myThread(threading.Thread):
def doA(self):
lockA.acquire()
print(self.name,"gotlockA",time.ctime())
time.sleep(3)
lockB.acquire()
print(self.name,"gotlockB",time.ctime())
lockB.release()
lockA.release()
def doB(self):
lockB.acquire()
print(self.name,"gotlockB",time.ctime())
time.sleep(2)
lockA.acquire()
print(self.name,"gotlockA",time.ctime())
lockA.release()
lockB.release()
def run(self):
self.doA()
self.doB()
if __name__=="__main__":
lockA=threading.Lock()
lockB=threading.Lock()
threads=[]
for i in range(5):
threads.append(myThread())
for t in threads:
t.start()
for t in threads:
t.join()#等待线程结束。#程序会在中间锁死
- 递归锁
为了解决死锁问题
import threading,time
class myThread(threading.Thread):
def doA(self):
RL.acquire()
print(self.name,"gotlockA",time.ctime())
time.sleep(3)
RL.acquire()
print(self.name,"gotlockB",time.ctime())
RL.release()
RL.release()
def doB(self):
RL.acquire()
print(self.name,"gotlockB",time.ctime())
time.sleep(2)
RL.acquire()
print(self.name,"gotlockA",time.ctime())
RL.release()
RL.release()
def run(self):
self.doA()
self.doB()
if __name__=="__main__":
RL=threading.RLock()
threads=[]
for i in range(5):
threads.append(myThread())
for t in threads:
t.start()
for t in threads:
t.join()