管程
为什么要引入管程
信号量机制存在的问题是:编写程序困难、易出错
很容易出现死锁。
管程的定义和基本特征
和之前的pv操作一样,也是来实现同步和互斥的
1.局部于管程的共享数据结构说明;
2.对该数据结构进行操作的一组过程;
过程:函数
3.对局部于管程的共享数据设置初始值的语句;
4.管程需要有一个名字;
有一点类似于class
管程的基本特征
1.局部于管程的数据只能被局部于管程的过程锁访问;
2.一个进程只有通过调用管程内的过程才能进入管程访问共享数据;
3.每次仅允许一个进程在管程内执行某个内部过程;
import threading
class Monitor:
def __init__(self):
self.lock = threading.Lock()
self.condition_vars = {} # 条件变量字典
def define_condition(self, name):
"""定义条件变量"""
self.condition_vars[name] = threading.Condition(self.lock)
def wait(self, cond_name):
"""在条件变量上等待"""
with self.condition_vars[cond_name]:
self.condition_vars[cond_name].wait()
def signal(self, cond_name):
"""唤醒条件变量上的一个线程"""
with self.condition_vars[cond_name]:
self.condition_vars[cond_name].notify()
def signal_all(self, cond_name):
"""唤醒条件变量上的所有线程"""
with self.condition_vars[cond_name]:
self.condition_vars[cond_name].notify_all()
# 示例:生产者-消费者模型
class BoundedBuffer:
def __init__(self, max_size):
self.monitor = Monitor()
self.monitor.define_condition("not_full")
self.monitor.define_condition("not_empty")
self.buffer = []
self.max_size = max_size
def produce(self, item):
with self.monitor.lock:
while len(self.buffer) >= self.max_size:
self.monitor.wait("not_full")
self.buffer.append(item)
self.monitor.signal("not_empty")
def consume(self):
with self.monitor.lock:
while len(self.buffer) == 0:
self.monitor.wait("not_empty")
item = self.buffer.pop(0)
self.monitor.signal("not_full")
return item
if __name__ == "__main__":
buffer = BoundedBuffer(5)
def producer():
for i in range(10):
buffer.produce(i)
print(f"Produced: {i}")
def consumer():
for _ in range(10):
item = buffer.consume()
print(f"Consumed: {item}")
t1 = threading.Thread(target=producer)
t2 = threading.Thread(target=consumer)
t1.start()
t2.start()
t1.join()
t2.join()
最后用我们比较熟悉的屁眼通红来实现一下管存吧
这个其实编译器已经封装好了,程序员不需要关心这些互斥和同步的问题