0

So I know writers release the priority lock too early. The lock should only be released by a writer if it knows that no other writer is in the queue. For example, if a writer is now executing in its critical state, the next writer will be stuck on resource_lock. The next reader will also be stuck on resource_lock. Since both the next writer and reader are now waiting for access to the >same< lock (resource_lock), there is no longer any priority for either thread type. When resource_lock is unlocked by the first writer, either reader or writer can enter. How do I solve this in the easiest way?

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


priority_lock = Lock() #priority lock
reader_lock = Lock() #lock for readers
# writer_lock = Lock() #lock for writers
resource_lock = Lock() #Lock for RESOURCE
reader_counter = 0

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

class Reader(Thread):
    def run(self):
        global reader_counter
        while(True):
            #check
            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()
            priority_lock.release()

            resource_lock.acquire()
            resource = datetime.now().strftime("%H:%M:%S")
            reverse = datetime.now().strftime("%S:%M:%H")
            print("ReversedWriter " + reverse)
            resource_lock.release()
            
            time.sleep(0.1)

class Writer(Thread):
    def run(self):
        global resource
        while True:
            priority_lock.acquire()
            priority_lock.release()

           
            resource_lock.acquire()
            resource = datetime.now().strftime("%H:%M:%S")
       
            print("Writer " + resource) 
            resource_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()
5
  • 1
    What's the purpose of priority_lock? It seems you only ever acquire and release it without doing anything. And just to clarify, you're trying to give readers priority over writers?
    – BoppreH
    Commented Feb 29, 2024 at 18:37
  • @BoppreH The purpose of priority_lock is to give writers priority over readers, but there lies the problem as the lock is released too early. Commented Feb 29, 2024 at 18:46
  • Writers aren't supposed to have priority over readers. Rather, they request exclusive access to a resource, rather than inclusive access. If you request exclusive access, you still need to wait for readers with inclusive access to finish, but other readers requesting access after you do not block you. When one writer releases the exclusive access lock, that doesn't mean the next writer gets it immediately, only that they can get it once the readers ahead of it finish.
    – chepner
    Commented Feb 29, 2024 at 19:45
  • It doesn't really mean anything to acquire and immediately release a lock without doing something in between.
    – chepner
    Commented Feb 29, 2024 at 19:46
  • I think what you want is the solution to the third readers-writers problem. Basically, readers and writers both get in the same line. When a reader reaches the front, they wait for a writer to finish or for "enough" readers to finish to give them access. When a writer reaches the front, they wait for all readers or the writer to finish, then get access. In both cases, the next actor (whether reader or writer) block everyone behind them in line.
    – chepner
    Commented Feb 29, 2024 at 19:48

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.