You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

读写者问题优化:如何解决Writer过早释放Priority Lock的问题?

问题根源与解决方法

问题分析

当前代码里的Writer拿到priority_lock后立刻释放,导致后续的Reader也能抢到priority_lock,接着Writer和Reader都卡在resource_lock的等待队列里。因为两者等的是同一把锁,原本设计的Writer优先级就失效了——第一个Writer释放resource_lock后,Reader和Writer谁先抢到谁执行,没法保证Writer优先。

最简单的解决方法

让Writer在操作资源的整个周期内持有priority_lock:把priority_lock的释放操作放在resource_lock释放之后。这样一来,只要有Writer在操作资源,priority_lock就会被牢牢占着,其他Writer和Reader都拿不到这把锁,只能排队等。等当前Writer完成资源操作、释放resource_lock后,再释放priority_lock,此时排队的Writer会优先抢到锁,保证Writer的优先级。

修改后的代码

from threading import Thread
from threading import Lock
from datetime import datetime
import time


priority_lock = Lock() # 优先级锁
reader_lock = Lock() # 读者计数锁
resource_lock = Lock() # 资源锁
reader_counter = 0

resource = datetime.now().strftime("%H:%M:%S")

class Reader(Thread):
    def run(self):
        global reader_counter
        while(True):
            # 先获取优先级锁,保证没有Writer在排队时才进入
            priority_lock.acquire()
            priority_lock.release()

            with reader_lock: 
                reader_counter += 1
                if reader_counter == 1: 
                    resource_lock.acquire()
            
            print("Reader: " + resource)

            with reader_lock:
                reader_counter -=1
                if reader_counter == 0:
                    resource_lock.release()
            time.sleep(0.1)

class ReversedWriter(Thread):
    def run(self):
        global resource
        while True:
            priority_lock.acquire()  # 先拿优先级锁,锁住后续的Reader和Writer
            resource_lock.acquire()  # 再拿资源锁操作资源
            
            resource = datetime.now().strftime("%H:%M:%S")
            reverse = datetime.now().strftime("%S:%M:%H")
            print("ReversedWriter " + reverse)
            
            resource_lock.release()  # 先释放资源锁
            priority_lock.release()  # 最后释放优先级锁,让后续线程可以抢锁
            time.sleep(0.1)

class Writer(Thread):
    def run(self):
        global resource
        while True:
            priority_lock.acquire()  # 持有优先级锁直到资源操作完成
            resource_lock.acquire()
            
            resource = datetime.now().strftime("%H:%M:%S")
            print("Writer " + resource) 
            
            resource_lock.release()
            priority_lock.release()
            time.sleep(0.1)
            
R1 = Reader()
R2 = Reader()
R3 = Reader()

W1 = Writer()
W2 = ReversedWriter()

R1.start()
R2.start()
R3.start()
W1.start()
W2.start()

逻辑说明

  • Writer操作时,先拿priority_lock再拿resource_lock,直到资源操作完成后才依次释放,期间所有Reader和其他Writer都无法获取priority_lock,也就没法进入资源等待队列,保证了Writer的优先级。
  • Reader的逻辑保持不变:必须先拿到priority_lock才能进入读取流程,确保只有当没有Writer在操作或排队时,Reader才能批量读取资源。

内容的提问来源于stack exchange,提问作者Måns Bodin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 00:47:33