对Thread不了解的朋友,可以参看这篇:Python多线程之Thread类。
大家都知道,要把大象装冰箱,总共分三步:把冰箱门打开、把大象装进去、把冰箱门关上,尤其想把多个大象装进多个冰箱的时候,更要注意这一点。
如果简化成简单的判断:如果这个冰箱里没有大象,则把大象装进这个冰箱,就会出现很严重的后果:
α
\alpha
α和
β
\beta
β同时发现冰箱A里没有大象,于是分别把大象a和b装进了冰箱A——这就十分危险了。
所以,在把大象装进冰箱之前,一定要先判断这个门是不是开着,如果门是开的,那不好意思,这个冰箱已经有人用了;如果门是关的,那么好了,打开冰箱看看里面有没有大象。
线程锁,就相当于是冰箱门,如果不开门直接判断,那么结果如下
from random import randint
from threading import Thread
from time import sleep
fridges = [0 for _ in range(10)]
def e2f():
for x in range(10):
if fridges[x]==0:
sleep(0.1)
fridges[x] += 1
return x
ths = [Thread(target=e2f) for _ in range(10)]
for t in ths: t.start()
最后一看,果然大象都装第一个冰箱里了,因为每个线程在判断的时候,第一个冰箱都是空的。
>>> fridges
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0]
如果使用lock ,看看会有什么好的结果没。。
from threading import Thread, RLock
from time import sleep
lock = RLock()
fridges = [0 for _ in range(10)]
def e2f():
for x in range(10):
if fridges[x]==0:
sleep(0.1)
fridges[x] += 1
return x
def E2FwithLock(L):
while(True):
if L.acquire(False):
e2f()
L.release()
ths = [Thread(target=E2FwithLock,args=[lock]) for _ in range(10)]
for t in ths: t.start()
由于阻塞的原因,这个程序会运行得很慢,但最后得到的结果是比较不错的
>>> fridges
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|