怎么在Python项目中实现一个读写锁

  介绍

这篇文章给大家介绍怎么在Python项目中实现一个读写锁,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

<强>简单的实现

import 线程      class  RWlock(对象):   def 才能__init__(自我):   ,,,self._lock =, threading.Lock ()   ,,,self._extra =, threading.Lock ()   ,,,self.read_num =0      def 才能read_acquire(自我):   ,,,with  self._extra:   ,,,,,self.read_num  +=1   ,,,,,if  self.read_num ==, 1:   ,,,,,,,self._lock.acquire ()      def 才能read_release(自我):   ,,,with  self._extra:   ,,,,,self.read_num  -=1   ,,,,,if  self.read_num ==, 0:   ,,,,,,,self._lock.release ()      def 才能write_acquire(自我):   ,,,self._lock.acquire ()      def 才能write_release(自我):   ,,,self._lock.release ()

这是读写锁的一个简单的实现,自我。read_num用来保存获得读锁的线程数,这个属性属于临界区,对其操作也要加锁,所以这里需要一个保护内部数据的额外的锁的自我。_extra .

但是这个锁是不公平的。理想情况下,线程获得所的机会应该是一样的,不管线程是读操作还是写操作。而从上述代码可以看的到,读请求都会立即设置的自我。read_num +=1,不管有没有获得锁,而写请求想要获得锁还得等待read_num为0。

所以这个就造成了只有锁没有被占用或者没有读请求时,可以获得写权限。我们应该想办法避免读模式锁长期占用。

<强>读写锁的优先级

读写锁也有分读优先和写优先上。面的代码就属于读优先。

如果要改成写优先,那就换成去记录写线程的引用计数,读和写在同时竞争时,可以让写线程增加写的计数,这样可使读线程的读锁一直获取不到,因为读线程要先判断写的引用计数,若不为0,则等待其为0,然后进行读。这部分代码不罗列了。

但这样显然不够灵活。我们不需要两个相似的读写锁类。我们希望重构我们代码,使它更强大。

<强>改进

为了能够满足自定义优先级的读写锁,要记录等待的读写线程数,并且需要两个条件线程。用条件来处理哪方优先的通知。计数引用可以扩大语义:正数:表示正在读操作的线程数,负数:表示正在写操作的线程数(最多1)

在获取读操作时,先然后判断时候有等待的写线程,没有,进行读操作,有,则等待读的计数加1后等待条件通知;等待读的计数减1,计数引用加1,继续读操作,若条件不成立,循环等待;

在获取写操作时,若锁没有被占用,引用计数减1,若被占用,等待写线程数加1,等待写条件条件的通知。

读模式和写模式的释放都是一样,需要根据判断去通知对应的条件:

class  RWLock(对象):   def 才能__init__(自我):   ,,,self.lock =, threading.Lock ()   ,,,self.rcond =, threading.Condition (self.lock)   ,,,self.wcond =, threading.Condition (self.lock)   ,,,self.read_waiter =, 0,, #,等待获取读锁的线程数   ,,,self.write_waiter =, 0,, #,等待获取写锁的线程数   ,,,self.state =, 0,,,,, #,正数:表示正在读操作的线程数,,负数:表示正在写操作的线程数(最多1)   ,,,self.owners =,[],,,, #,正在操作的线程id集合   ,,,self.write_first =, True  #,默认写优先,假表示读优先      def 才能write_acquire(自我,,阻止=True):   ,,,#,获取写锁只有当   ,,,me =, threading.get_ident ()   ,,,with  self.lock:   ,,,,,while  not  self._write_acquire(我):   ,,,,,,,if  not 阻塞:   ,,,,,,,,,return 错误的   ,,,,,,,self.write_waiter  +=1   ,,,,,,,self.wcond.wait ()   ,,,,,,,self.write_waiter  -=1   ,,,return 真实的      def 才能_write_acquire(自我,,我):   ,,,#,获取写锁只有当锁没人占用,或者当前线程已经占用   ,,,if  self.state ==, 0,趁机(self.state  & lt;, 0,以及me 拷贝self.owners):   ,,,,,self.state  -=1   ,,,,,self.owners.append(我)   ,,,,,return 真实的   ,,,if  self.state 祝辞,0,以及me 拷贝self.owners:   ,,,,,raise  RuntimeError (& # 39; cannot  recursively  wrlock  a  rdlocked 锁# 39;)   ,,,return 错误的      def 才能read_acquire(自我,,阻止=True):   ,,,me =, threading.get_ident ()   ,,,with  self.lock:   ,,,,,while  not  self._read_acquire(我):   ,,,,,,,if  not 阻塞:   ,,,,,,,,,return 错误的   ,,,,,,,self.read_waiter  +=1   ,,,,,,,self.rcond.wait ()   ,,,,,,,self.read_waiter  -=1   ,,,return 真实的      def 才能_read_acquire(自我,,我):   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

怎么在Python项目中实现一个读写锁