管程

为什么要引入管程

信号量机制存在的问题是:编写程序困难、易出错

很容易出现死锁。

管程的定义和基本特征

和之前的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()

最后用我们比较熟悉的屁眼通红来实现一下管存吧

这个其实编译器已经封装好了,程序员不需要关心这些互斥和同步的问题

posted @ 2025-09-29 16:18  是我,米老鼠  阅读(8)  评论(0)    收藏  举报