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