读者写者问题

2017-02-14  本文已影响0人  IT孤独者

读者写者问题是IPC问题的一种典型的代表。

我写了一个实现,这是一个写者优先的实现。一个写者,多个读者的模型。

读者写者问题有一个典型的思路,就是计数加锁,如果读者共享一份资源,那么对于读者来说,只要第一个读者锁住资源,然后读者计数,最后一个离开的读者在解锁资源,这就是计数加锁,这个模型是消费者生产者不具备的模型思路

代码如下:

import threading

class RDSource:
    def __init__(self):
        self._mtx = threading.Lock()
        self._mtx_write_flag = threading.Lock()
        self._con_write_flag = threading.Condition(self._mtx_write_flag)
        self._write_flag = False
        self._mtx_read_count = threading.Lock()
        self._read_count = 0

    def read(self):
        # check writer
        self._con_write_flag.acquire()
        while (self._write_flag == True):
            self._con_write_flag.wait()
        self._con_write_flag.release()

        self._mtx_read_count.acquire()
        self._read_count += 1
        if (self._read_count == 1):
            self._mtx.acquire()
        self._mtx_read_count.release()

        # read source

        self._mtx_read_count.acquire()
        self._read_count -= 1
        if (self._read_count == 0):
            self._mtx.release()
        self._mtx_read_count.release()

        # return read source

    def write(self):
        self._write_flag = True
        self._mtx.acquire()

        # write resouce

        self._mtx.release()
        self._write_flag = False
        self._con_write_flag.acquire()
        self._con_write_flag.notify_all()
        self._con_write_flag.release()

实用代码如下:

import threading
import queue
import time

class RDSource:
    def __init__(self):
        self._mtx = threading.Lock()
        self._mtx_write_flag = threading.Lock()
        self._con_write_flag = threading.Condition(self._mtx_write_flag)
        self._write_flag = False
        self._mtx_read_count = threading.Lock()
        self._read_count = 0

        self._lr = []

    def read(self):
        # check writer
        self._con_write_flag.acquire()
        while (self._write_flag == True):
            self._con_write_flag.wait()
        self._con_write_flag.release()

        self._mtx_read_count.acquire()
        self._read_count += 1
        if (self._read_count == 1):
            self._mtx.acquire()
        self._mtx_read_count.release()

        # read source
        rt = self._lr
        # print(len(self._lr))

        self._mtx_read_count.acquire()
        self._read_count -= 1
        if (self._read_count == 0):
            self._mtx.release()
        self._mtx_read_count.release()

        # return read source

        return rt

    def write(self, item):
        self._write_flag = True
        self._mtx.acquire()

        # write resouce
        self._lr.append(item)

        self._mtx.release()
        self._write_flag = False
        self._con_write_flag.acquire()
        self._con_write_flag.notify_all()
        self._con_write_flag.release()

class Print:
    def __init__(self):
        self._mtx = threading.Lock()

    def __call__(self, item):
        self._mtx.acquire()
        print(item)
        self._mtx.release()


class Writer(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self._l = ['hello', 'world', 'hello', 'world']
        pass

    def run(self):
        global rdSource
        for item in self._l:
            rdSource.write(item)
            time.sleep(1)

        # print('writer end')

class Reader(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        pass

    def run(self):
        global print_
        item = rdSource.read()
        print_(item)

rdSource = RDSource()
print_ = Print()
def main():
    global  rdSource
    w = Writer()
    w.start()

    for i in range(1, 40000):
        r = Reader()
        r.start()


if __name__ == '__main__':
    main()

从输出的结果可以看出,读者和写者有序的进行着
输出如下:

C:\Python3\python.exe D:/PycharmProjects/untitled4/main.py
。。。。
Process finished with exit code 0

上一篇下一篇

猜你喜欢

热点阅读