Python--互斥锁|递归锁|死锁机制详解

互斥锁:牺牲了执行效率而获得数据安全

问题:

# 多个线程抢占资源,会发生数据混乱
from threading import Thread
import os,time
def work():
    global n
    temp=n
    time.sleep(0.1)
    n=temp-1
if __name__ == '__main__':
    n=100
    l=[]
    for i in range(100):
        p=Thread(target=work)
        l.append(p)
        p.start()
    for p in l:
        p.join()

    print(n) #结果可能为99

解决:

# 引入锁(Lock)的介入,一把钥匙配一把锁
from threading import Thread,Lock
import os,time
def work():
    global n
    lock.acquire()
    temp=n
    time.sleep(0.1)
    n=temp-1
    lock.release()
if __name__ == '__main__':
    lock=Lock()
    n=100
    l=[]
    for i in range(100):
        p=Thread(target=work)
        l.append(p)
        p.start()
    for p in l:
        p.join()

    print(n) #结果肯定为0,由原来的并发执行变成串行,牺牲了执行效率保证了数据安全

 


死锁:

# 这时fork的锁拿到了一些资源,noodle拿到了一些资源,互不相让,造成死锁
import time
from threading import Thread,Lock
fork_lock = noodle_lock = Lock()

fork_lock.acquire()
print(222)
noodle_lock.acquire()
print(333)
fork_lock.release()
noodle_lock.release()
print(111)

递归锁:解决死锁

import time
from threading import Thread,RLock
fork_lock = noodle_lock = RLock()
def eat1(name):
    # 死锁就是noodle_lock抢到的钥匙也能打开下面的fork_lock
    noodle_lock.acquire()
    print('%s 抢到了面条111'%name)
    fork_lock.acquire()
    print('%s 抢到了叉子222'%name)
    print('%s 吃面333'%name)
    fork_lock.release()
    noodle_lock.release()

def eat2(name):
    # 这个相当于跟上面的递归锁是同一级的,所以上面抢到了,这个必须等到上述递归锁的counter为0
    # 也就是所有的资源都release掉了之后,才释放资源
    fork_lock.acquire()
    print('%s 抢到了叉子555' % name)
    time.sleep(1)
    noodle_lock.acquire()
    print('%s 抢到了面条666' % name)
    print('%s 吃面777' % name)
    noodle_lock.release()
    fork_lock.release()

for name in ['哪吒','egon','yuan']:
    t1 = Thread(target=eat1,args=(name,))
    t2 = Thread(target=eat2,args=(name,))
    t1.start()
    t2.start()

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页