#1、锁:防止多个线程同时读写某一块内存区域。 from threading import Thread from threading import Lock def func(): global n lock.acquire() n -= 1 #每一个线程在操作数据之前先拿到钥匙,操作完成之后,释放钥匙。 lock.release() n = 10 t_list = [] lock = Lock() for i in range(10): #先开启所有子线程。 t = Thread(target=func) t.start() t_list.append(t) [t.join() for t in t_list] #最后才让主线程等待所有子线程结束而结束。这样才能实现异步操作。 print(n) #2、RLock递归锁可以acquire多次和对应地release多次,Lock互斥锁只能acquire和release一次。 from threading import RLock lock = RLock() lock.acquire() lock.acquire() lock.acquire() print('123') lock.release() lock.release() lock.release() #123 # 3、死锁:在不同的线程当中(eat和eat1),恰好要对两个数据(筷子和面)进行操作,使用Lock会产生死锁,数据不安全。 # 科学家吃面:吃面需要同时有筷子和面才能吃到,A吃完面把筷子和面放下让给B,B拿到筷子和面才能吃。 # 下面例子的结果是有人拿到面拿不到筷子,有人拿到筷子拿不到面,形成死锁。 from threading import Lock from threading import Thread import time def eat(name): kz_lock.acquire() print('%s拿到筷子了'%name) m_lock.acquire() print('%s拿到面了'%name) print('%s可以吃面了'%name) time.sleep(1)#因为cpu调度是无序的,设置睡眠1秒是为了把问题更好的发掘出来,否则就算执行很多次,出现问题是小概率事件。 m_lock.release() kz_lock.release() def eat1(name): m_lock.acquire() print('%s拿到面了'%name) kz_lock.acquire() print('%s拿到筷子了'%name) print('%s可以吃面了'%name) kz_lock.release() m_lock.release() kz_lock = Lock() #筷子锁 m_lock = Lock() #面锁 t = Thread(target=eat,args=('tom',)) t.start() t1 = Thread(target=eat1,args=('marry',)) t1.start() t2 = Thread(target=eat,args=('jack',)) t2.start() t3 = Thread(target=eat1,args=('alex',)) t3.start() # tom拿到筷子了 # tom拿到面了 # tom可以吃面了 # jack拿到筷子了 # marry拿到面了 #Rlock解决死锁问题: from threading import RLock from threading import Thread import time def eat(name): kz_lock.acquire() print('%s拿到筷子了'%name) m_lock.acquire() print('%s拿到面了'%name) print('%s可以吃面了'%name) time.sleep(1) m_lock.release() #后面拿到的钥匙先还。 kz_lock.release() #前面拿到的钥匙后还。 def eat1(name): m_lock.acquire() print('%s拿到面了'%name) kz_lock.acquire() print('%s拿到筷子了'%name) print('%s可以吃面了'%name) kz_lock.release() m_lock.release() kz_lock = m_lock = RLock() #筷子锁和面锁是同一把锁 t = Thread(target=eat,args=('tom',)) t.start() t1 = Thread(target=eat1,args=('marry',)) t1.start() t2 = Thread(target=eat,args=('jack',)) t2.start() t3 = Thread(target=eat1,args=('alex',)) t3.start() # tom拿到筷子了 # tom拿到面了 # tom可以吃面了 # marry拿到面了 # marry拿到筷子了 # marry可以吃面了 # jack拿到筷子了 # jack拿到面了 # jack可以吃面了 # alex拿到面了 # alex拿到筷子了 # alex可以吃面了 #Rlock解决死锁问题(更加简洁的写法): from threading import RLock from threading import Thread def eat(name): lock.acquire() print('%s拿到筷子了'%name) lock.acquire() print('%s拿到面了'%name) print('%s可以吃面了'%name) lock.release() lock.release() def eat1(name): lock.acquire() print('%s拿到面了'%name) lock.acquire() print('%s拿到筷子了'%name) print('%s可以吃面了'%name) lock.release() lock.release() lock = RLock() t = Thread(target=eat,args=('tom',)) t.start() t1 = Thread(target=eat1,args=('marry',)) t1.start() t2 = Thread(target=eat,args=('jack',)) t2.start() t3 = Thread(target=eat1,args=('alex',)) t3.start()