Reader Writer Problem

void read()
{
  while(true):
  {
    P(r);
    rc++;
    if(rc == 1)
      P(w);
    V(r);

    // read

    P(r);
    rc--;
    if(rc == 0)
      V(w);
    V(r);
  }
}

This piece of code use simpy to implement reader writer problem. And besides, it can avoid writer starvation problem:

  • It set up and maximum reading time.

  • When it detects there is too many readers reading, new coming reader thread has to wait certain amount of time to allow the writer be able to access the shared resource.

code


import simpy
import random
rc = 0
req = None
max_operation_time = 5


class reader_manager(object):
    def __init__(self, env, lock):
        self.env = env
        self.task_list = []
        self.action = env.process(self.run())
        self.est_time = env.now
        self.lock = lock

    def addTask(self, reader_index, reading_time):
        self.task_list.append((reader_index, reading_time))

    def run(self):

        global rc
        while True:
            yield self.env.timeout(0.2)
            #if len(self.task_list) > 4:
            if rc > 3:
                print('too many tasks (%s)' % rc)
                #print('too many tasks (%s)' % len(self.task_list))
                yield env.timeout(max_operation_time * 2 + 1)

            if not self.task_list:
                continue

            reader_idx = self.task_list[0][0]
            reading_time = self.task_list[0][1]

            self.task_list.pop(0)

            #print('%s %s %s' % (env.now, reader_idx, reading_time))
            self.env.process(reader(self.env, self.lock, reader_idx, reading_time))

def reader(env, lock,reader_index, reading_time):
    global rc
    global req

    rc = rc+1
    if rc == 1:
        req = lock.request()
        yield req
    print("%s reader is reading at %s" %(reader_index,env.now))
    yield env.timeout(reading_time)
    print("%s reader has finished reading at %s" %(reader_index,env.now))
    rc = rc-1
    if rc == 0:
        lock.release(req)
    yield env.timeout(0.1)


def writer(env, lock):
    while True:
        yield env.timeout(random.randint(0, 5))
        with lock.request() as req:
            yield req
            print("I am writing! at %s" %env.now)
            yield env.timeout(random.randint(0, 10))
            print("I have finished writing at %s" %env.now)




def task_gen(env, rm):
    idx = 0
    while True:
        #t = random.randint(0, 2)
        yield env.timeout(2)
        #print('%s' % t)
        #rm.addTask(random.randint(0, 10), random.randint(0, 10))
        rm.addTask(idx, random.randint(0, 10))
        idx = idx + 1

env = simpy.Environment()
lock = simpy.Resource(env, capacity=1)
#lockcount = simpy.Resource(env, capacity=1)

rm = reader_manager(env, lock)
env.process(task_gen(env, rm))
env.process(writer(env, lock))
#rm.addTask(1, 15)
#rm.addTask(2, 15)
#rm.addTask(3, 15)
#rm.addTask(4, 15)
env.run(until=200)

#env.process(reader(env, lock, 1, random.random()))
#env.process(reader(env, lock, 2, random.random()))
#env.process(reader(env, lock, 3, random.random()))
#env.process(reader(env, lock, 4, random.random()))
#env.process(writer(env, lock,2))

#env.run(until=15)

results matching ""

    No results matching ""