读者写者问题----写者优先(python测试)
读者写者问题——写者优先(python测试)
- 问题描述
- 限制条件
- 利用写者优先策略
- 测试
- 输出
- 总结
问题描述
一个数据对象若被多个并发进程所共享,且其中一些进程只要求读该数据对象的内容,而另一些
进程则要求写操作,对此,把只想读的进程称为“读者”,而把要求写的进程称为“写者”。在
读者–写着问题中,任何时刻要求“写者”最多只允许有一个,而读者则允许有多个。因为多个
读者的行为互不干扰,他们只是读数据,而不改变数据对象的内容,而写者则不同,他们要改变数据对象的内容,如果他们同时操作,则数据对象的内容将会改变的不可知。
限制条件
- 允许任意多的读进程同时读;
- 一次只允许一个写进程写操作;
- 如果有一个写进程正在进行写操作,禁止任何读进程进行读操作。
利用写者优先策略
即当一个写者到来时,只有那些已经获得授权允许读的进程才允许完成他们的操作,写者之后到来的读者将被推迟,直到写者完成。
为了解决“写着与写着”和“写着与第一个读者”的互斥问题即可,为此引入互斥信号量File。为了记录谁是第一个读者,可以用一个全局整型变量Rcount做一个计数器。而在解决问题的过程中,由于使用了全局变量Rcount,该变量又是一个临界资源,对于他的访问仍需互斥进行,所以需要一个互斥信号量Rmutex。记录等待与运行的写者数量引入一个全局变量Wcount,同时该变量又是一个临界资源,对于他的访问仍需互斥进行,所以需要一个互斥信号量Wmutex。
测试
import time
import threading
from threading import Semaphore
import random
Rcount = 0 # 进行的读者队列数量
Wcount = 0 # 进行的写者队列数量
Wmutex = Semaphore(1) # 对临界资源Wcount的互斥访问
Rmutex = Semaphore(1) # 对临界资源Rcount的互斥访问
File = Semaphore(1) # 解决“写着与写着”和“写着与第一个读者”的互斥问题
Wirte = Semaphore(1) # 表示写者进程
def reader(i):
print('reader'+str(i)+' waiting to read\n', end='')
Wirte.acquire()
Rmutex.acquire()
global Rcount
if Rcount == 0:
File.acquire()
Rcount += 1
Rmutex.release()
Wirte.release()
print('reader'+str(i)+' reading\n', end='')
time.sleep(random.randint(1, 5))
print('reader'+str(i)+' finish read\n', end='')
Rmutex.acquire()
Rcount -= 1
if Rcount == 0:
File.release()
Rmutex.release()
def writer(i):
print('writer'+str(i)+' waiting to write\n', end='')
Wmutex.acquire()
global Wcount
if Wcount == 0:
Wirte.acquire()
Wcount += 1
Wmutex.release()
File.acquire()
print('writer'+str(i)+' writing\n', end='')
time.sleep(random.randint(1, 5))
print('writer'+str(i)+' finish write\n', end='')
File.release()
Wmutex.acquire()
Wcount -= 1
if Wcount == 0:
Wirte.release()
Wmutex.release()
if __name__ == '__main__':
times = 10
rwlist = []
for _ in range(times):
rwlist.append(random.randint(0, 1))
print(rwlist)
print('其中1表示读者进程,0表示写者进程')
rindex = 1
windex = 1
for i in rwlist:
if i == 1:
t = threading.Thread(target=reader, args=(rindex, ))
rindex += 1
t.start()
else:
t = threading.Thread(target=writer, args=(windex, ))
windex += 1
t.start()
输出
[1, 1, 1, 0, 0, 0, 1, 1, 0, 1]
其中1表示读者进程,0表示写者进程
reader1 waiting to read
reader1 reading
reader2 waiting to read
reader2 reading
reader3 waiting to read
reader3 reading
writer1 waiting to write
writer2 waiting to write
writer3 waiting to write
reader4 waiting to read
reader5 waiting to read
writer4 waiting to write
reader6 waiting to read
reader1 finish read
reader3 finish read
reader2 finish read
writer1 writing
writer1 finish write
writer2 writing
writer2 finish write
writer3 writing
writer3 finish write
writer4 writing
writer4 finish write
reader4 reading
reader5 reading
reader6 reading
reader4 finish read
reader5 finish read
reader6 finish read
Process finished with exit code 0
总结
在该策略中,如果有一个不可中断的连续的写者,读者进程会被无限期的推迟。
还没有评论,来说两句吧...