三种锁:互斥锁Lock,递归锁Rlock,信号量Samaphore

互斥锁:牺牲了效率,得到了数据安全,串行了。 缺点:acqueire后其他进程必须等到该进程release后才能继续拿到锁,可能会出现死锁情况。

def demo():
    mutex.acquire()
    print('%s 拿到了A锁' % current_thread().getName())
    time.sleep(2)
    mutex.release()
    print('%s 拿到了B锁' % current_thread().getName())

if __name__ == '__main__':
    mutex = Lock()
    t = Thread(target=demo)
    t1 = Thread(target=demo)
    t2 = Thread(target=demo)
    t.start()
    t1.start()
    t2.start()

执行结果:

>>>Thread-1 拿到了A锁
>>>Thread-1 拿到了B锁
>>>Thread-2 拿到了A锁
>>>Thread-2 拿到了B锁
>>>Thread-3 拿到了A锁
>>>Thread-3 拿到了B锁

递归锁

在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。

这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。上面的例子如果使用RLock代替Lock,则不会发生死锁,二者的区别是:递归锁可以连续acquire多次,而互斥锁只能acquire一次

总结:

RLock可以多次acquire,每次acquire就相当于conuter+1,只要counter不为0,别的进程就无法拿到我锁。

from threading import Lock,RLock,Semaphore,Thread,current_thread
import time

def demo():
    mutexA.acquire()
    print('%s 拿到了A锁' % current_thread().getName())
    time.sleep(1)
    mutexB.acquire()
    print('%s 拿到了B锁' % current_thread().getName())
    mutexB.release()
    mutexA.release()
    demo1()


def demo1():
    mutexB.acquire()
    print('%s 拿到了B锁' % current_thread().getName())
    time.sleep(1)
    mutexA.acquire()
    print('%s 拿到了A锁' % current_thread().getName())
    mutexA.release()
    mutexB.release()


if __name__ == '__main__':
    mutexA = RLock()
    mutexB = mutexA
    t = Thread(target=demo)
    t1 = Thread(target=demo)
    t2 = Thread(target=demo)
    t.start()
    t1.start()
    t2.start()

信号量:

信号量也是一把锁,可以指定信号量为5,对比互斥锁同一时间只能有一个任务抢到锁去执行,信号量同一时间可以有5个任务拿到锁去执行,如果说互斥锁是合租房屋的人去抢一个厕所,那么信号量就相当于一群路人争抢公共厕所,公共厕所有多个坑位,这意味着同一时间可以有多个人上公共厕所,但公共厕所容纳的人数是一定的,这便是信号量的大小

from threading import Thread,Semaphore
import threading
import time


def func():
    with sm:
        print('%s get sm' % threading.current_thread().getName())
        time.sleep(1)


if __name__ == '__main__':
    sm = Semaphore(3)
    for i in range(10):
        t=Thread(target=func)
        t.start()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值