由于线程之间随机调度:某线程可能在执行n条后,CPU接着执行其他线程。为了多个线程同时操作一个内存中的资源时不产生混乱,我们使用锁。
Lock(指令锁)是可用的最低级的同步指令。Lock处于锁定状态时,不被特定的线程拥有。Lock包含两种状态——锁定和非锁定,以及两个基本的方法。
可以认为Lock有一个锁定池,当线程请求锁定时,将线程至于池中,直到获得锁定后出池。池中的线程处于状态图中的同步阻塞状态。
创建锁:
lock=threading.Lock()
cond=threading.Condition(lock=lock)
锁的方法:
cond.acquire(): 获得锁
cond.wait() 等待通知
cond.notify() 通知正在等待的锁
cond.notify_all() 通知所有正在等待的锁
cond.release() 释放锁
实例:
当多线程争夺锁时,允许第一个获得锁的线程进入临街区,并执行代码。
所有之后到达的线程将被阻塞,直到第一个线程执行结束,退出临街区,
并释放锁。需要注意,那些阻塞的线程是没有顺序的。
import threading,time
lista=[]
class huofu(threading.Thread):
def run(self):
while True:
condchi.acquire() #给吃货上锁怕他偷吃馒头
if len(lista)==0:
for i in range(1,11): #生产馒头
lista.append(i)
print("正在生产第{}个馒头".format(i))
time.sleep(1)
condchi.notify_all() #馒头已经生产完毕,通知吃货准备吃馒头
condchi.release() #给吃货解锁
class chihuo(threading.Thread):
def __init__(self,name):
threading.Thread.__init__(self)
self.name=name
def run(self):
mantou=[]
while True:
condchi.acquire() #吃货抢锁谁抢到谁进去吃馒头
if len(lista)>0:
mantou=lista.pop() #吃馒头
time.sleep(1)
else:
condhuo.acquire() #获得伙夫的锁
condhuo.notify() #通知伙夫准备做馒头
condhuo.release() #释放伙夫的锁
condchi.wait() #没馒头了吃货等待
condchi.release() #释放吃货的锁
if mantou not in lista:
print("{}在吃第{}个馒头".format(self.name,mantou))
lock1=threading.Lock()
condhuo=threading.Condition(lock1)
lock2=threading.Lock()
condchi=threading.Condition(lock2)
huofu1=huofu()
chihuo1=chihuo("handao") #生成吃货一
chihuo2=chihuo("tanzhenghua") #生成吃货二
chihuo3=chihuo("laowang") #吃货三
huofu1.start()
chihuo1.start()
chihuo2.start()
chihuo3.start()