【实验题目】:进程同步(互斥)
【实验学时】:4学时
【实验目的】
通过这次实验,加深对进程同步概念的理解,进一步掌握进程同步机制、进程同步算法和进程同步的评价。
【实验内容】
问题描述:
以生产者消费者模型为基础,在Windows环境下创建一个控制台进程(或者界面进程),在该进程中创建读者写者线程模拟生产者和消费者。写者线程写入数据,然后将数据放置在一个空缓冲区中供读者线程读取。读者线程从缓冲区中获得数据,然后释放缓冲区。当写者线程写入数据时,如果没有空缓冲区可用,那么写者线程必须等待读者线程释放出一个空缓冲区。当读者线程读取数据时,如果没有满的缓冲区,那么读入线程将被阻塞,直到新的数据被写进去。
实现提示:
本实验要求设计并实现一个进程,该进程拥有一个生产者线程和一个消费者线程,它们使用N个不同的缓冲区(N为一个确定的数值,本实验中取N=16)。你需要使用如下信号量:
一个互斥信号量mutex,用以阻止生产者线程和消费者线程同时操作缓冲区列表;
一个信号量full,当生产者线程生产出一个物品时可以用它向消费者线程发出信号;
一个信号量empty,消费者线程释放出一个空缓冲区时可以用它向生产者线程发出信号;
源代码:复制到Pycharm或者jupyter notebook可以直接跑!!!
import threading
import time
import random
count=0 #使用共享区的模拟变量
condition = threading.Condition()
class Producer(threading.Thread): #使创建的类继承threading.Thread
def __init__(self,threadName): #重写其构造方法
threading.Thread.__init__(self)
self.threadName = threadName
def run(self):
global count #引入全局变量
while True:
if condition.acquire(): #使用条件对象获取锁并锁定
if count>=16: #判断是否超过上限
print('共享区已满,生产者Producer进入阻塞状态,停止放入!')
condition.wait() #使当前进程进入阻塞状态
else:
count += 1 #放入缓冲区
msg = time.ctime()+' '+self.threadName+'生产了1件商品放入缓冲区,共享区总计商品个数:'+str(count)
print(msg)
condition.notify() #唤醒其他阻塞状态的进程
condition.release() #解除锁定
time.sleep(random.randrange(10)/5) #随机休息n秒
class Customer(threading.Thread): #消费者的线程类
def __init__(self,threadName):
threading.Thread.__init__(self)
self.threadName = threadName
def run(self):
global count
while True:
if condition.acquire():
if count < 1:
print("共享区为空,消费者Customer线程进入阻塞状态,停止获取!")
condition.wait() #当前进程进入阻塞状态
else:
count -= 1
msg=time.ctime()+' '+self.threadName + '消费了1件商品,共享区总计商品个数为:'+str(count)
print(msg)
condition.notify() #唤醒其他阻塞线程
condition.release() #解除锁定
time.sleep(random.randrange(10)/2) #随即休眠n秒
if __name__ == "__main__":
for i in range(2):
p = Producer('[生产者-'+str(i+1)+']')
p.start() #启动生产者线程
for i in range(5):
c = Customer('[消费者-'+str(i+1)+']')
c.start() #启动消费者线程
特别说明:需要手动终止运行,否则程序会一直进行输出!!!