美文网首页
读者写者问题

读者写者问题

作者: IT孤独者 | 来源:发表于2017-02-14 12:39 被阅读0次

    读者写者问题是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
    
    

    相关文章

      网友评论

          本文标题:读者写者问题

          本文链接:https://www.haomeiwen.com/subject/chuxwttx.html