线程同步中的一些锁、条件、信号量的解析

10 篇文章 0 订阅
3 篇文章 0 订阅

python threading 中的 Lock, RLock, Condition, Semaphore, Event

这些内容主要是用来控制在并发过程中,线程的同步行为的。

Lock

lock 是在控制同步中 常见且基础的对象。通过这个对象可以控制共享资源的串行访问。

需要注意: 锁的获取、释放, 防止死锁!

from threading import Lock

lock = Lock()

with lock:
    pass

当然可以添加两个参数, blocking, timeout 用来控制怎么获取锁。
可以阻塞, 可以超时,默认是阻塞无超时,就是一直等待下去。

默认参数: timeout=-1, blocking=True

RLock

重入锁。

为什么会出现:当时用普通的锁的时候,如果已经获取了锁,再次获取的时候,就会永久阻塞。也就是锁不会被释放
也不能再次被获取。这就造成了死锁。

解决方式:就是提供了一个类型的锁,重入锁, RLock

特点:就是已经获取到锁后当前线程可以再次获取。

内部实现: 基本锁是Lock, 内部是通过获取当前锁的持有人的ID, 每次获取的时候进行判断,是同一个就返回并给计数加1。
释放则不会直接把锁释放掉,而是计数减一,直到计数为0,才真正的释放屌内部锁

from threading import RLock

r_lock = RLock()

with r_lock:
    print(r_lock)
    with r_lock:
        print(r_lock)

输出:

<locked _thread.RLock object owner=5832 count=1 at 0x0000000002158B40>
<locked _thread.RLock object owner=5832 count=2 at 0x0000000002158B40>

可看到 count 变为了2, owner表示持有人为5832

Condition

条件,条件变量, 状态

为什么会出现: 假如有一个需求 是在某些顺序代码中 要不止一次控制暂停等待或者唤醒
如果单单的只是用一把普通的锁,多个任务(并发的同样的任务或是同时执行的不同的任务)也就只能停止等待一次,获取了锁,执行完就释放了。
那么如果要多次等待几次,那就同时多整几把锁,放到队列里面, 并且不同的并发的线程中的等待的锁不能一样。但是可以通过接口释放这些锁,达到唤醒目的。

同时,因为处于并发环境下,协调这些锁的时候为了避免锁队列内容不同步,需要有一把串行锁,保证协调的时候串行执行。同时也是防止等待超时之后直接顺序执行代码

怎么实现呢:

材料: 同步锁,锁队列

实现方式: 在需要等待的时候,先保证持有同步锁,生成一把普通的锁,加进锁队列,然后进行等待,同时释放转储同步锁,让其他线程使用。
同时要注意锁队列的清除,把超时的锁清除,和被唤醒的锁清除。清除完毕之后要重新获取同步锁,防止因阻塞锁超时释放而自动执行代码

通知接口: 通知接口会将所有的阻塞锁进行释放,让等待这些锁的断点进行执行。

需要注意的是:
在使用waitnotify的时候要先获取同步锁。

不关键的关键内容: wait 里面是怎么通过一把锁使得当前线程暂停的。

基本方式如下:

is_block = True
timeout = 3

from threading import Lock
lock_queue = []

simple_lock = Lock()
lock_queue.append(simple_lock)
simple_lock.acquire()
# 释放同步锁,让其他线程使用

simple_lock.acquire(block=is_block, timeout=timeout)
# 这样 这个顺序代码就被阻塞到这个地方了

其中这个simple_lock 就是用来阻断代码执行,只有等到 simple_lock 被其他线程释放,或是超时才能继续往下执行代码。

另外,超时之后,还要争用同步锁。

samephore

信号量

相对于普通的锁,增加了并发控制,可以认为的控制同时执行的线程个数

内部实现基于condition

event

事件

里面增加了标记,被称为事件信号,是condition的又一包装。 当标记被设置之后,唤醒所有等待事件信号的线程。
操作相对condition更加简单

内部实现:condition

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值