2024年6月9日发(作者:)

python线程锁的用法

Python线程锁是一种基于硬件并发控制机制,用于在多个线程间

保护临界资源的锁定方法。它把共享资源的访问局限在一个线程,避

免多线程访问出现问题,诸如“死锁”和“临界区”问题等。

Python线程锁通常有两类:互斥锁(mutex)和信号量

(semaphore)。

互斥锁(mutex)

互斥锁是控制多线程对共享数据的访问,同一时刻只允许一个线

程访问共享数据。保护共享数据不被其他线程修改,它只允许一次访

问。当有线程获取到了锁,其他线程就必须等待,而此时正在处理的

线程可以继续访问共享数据,直至释放锁。一旦释放锁,系统会把此

锁传给等待的线程。

Python的threading模块提供了Lock,Rlock和Semaphore等锁。

Lock(互斥锁)

Lock锁就像一个开关锁,可以打开或关闭来控制共享资源的访问,

在实现线程同步时,先获取锁定,然后进行操作,操作完成后释放锁

定。

(1)acquire():调用这个方法来获取锁,如果获取失败,线

程就进入阻塞状态,直到获取成功为止。

(2)release():调用这个方法来释放锁,释放锁存在两种情

况:释放与该线程相关联的锁;释放与该线程不相关联的锁。

(3)locked():返回锁是否被锁住,如果有先返回true,反之

返回false。

Rlock(可重入锁)

可重入锁有点像“互斥锁”,两者最大的不同是:“可重入锁”

允许一个线程多次获得同一把锁,而且每次线程释放该锁后,才真正

释放,因此一个线程可以访问许多次同一个资源,而" 互斥锁“不允

许同一个线程多次获得同一把锁,当释放锁时,就正式释放该锁。

Rlock()同样提供了acquire(),release()和locked()

三个方法,但 differs from Lock和Lock Rlock可以被一个线程多次

获取,不会造成死锁现象,只有获取同一把锁多次的线程去释放它,

锁才能真正的被释放。在多个线程访问共享资源的同一数据时,Rlock

可以保证同一时刻只有一个线程对 数据进行操作。

Semaphore(信号量)

信号量的目的是用于限制多线程对共享资源的访问,可以把信号

量理解为一组计数器,每次调用信号量上的acquire()方法就会检查

计数器,如果计数器大于1,说明有足够的资源,会把计数器减1,如

果计数器等于0,则线程将进入等待状态,直到计数器大于0,或者超

出设定的等待时间,线程才可以继续执行。

Semaphore提供了acquire(),release()和getvalue()三

个方法:

(1)acquire():这个方法功能类似Rlock,可以保证多个线程

同时访问资源,但它是提供有限资源的,可以控制同一时刻有多少个

线程在访问共享资源;

(2)release():当线程不需要访问资源时,调用release()

释放锁定,使得计数器加1,表示有可用的资源;

(3)getvalue():这个方法的功能是返回Semaphore的当前计

数值。

Python线程锁是用来保护临界资源的,它可以帮助我们避免死锁

和临界区的问题,可以控制同一时刻有多少个线程在访问共享资源,

比如互斥锁(mutex)、可重入锁(Rlock)和信号量(Semaphore)等。

使用线程锁时,应该用try/except,在释放锁之前检查是否可以释放,

如果发生死锁,可以在程序结束之前,手动释放线程锁。