1.程序框架分析:
a)首先将mutex, condition, queue 封装成各自的类,方便对外提供接口函数,这里要注意 condition的封装,一个条件变量和一把锁是一起用的,因此在初始化 condition 对象的时候要用一个 mutex 对象去初始化,在pthread_cond_wait函数中还要用到互斥锁中的指针,因此在mutex 类中要封装一个返回相应类型的函数。此外多个条件变量一般是和同一互斥锁进行交互,因此要在condition 中的 mutex对象设为引用,这里可以这样想,如果不加引用,那么这个条件变量初始化后就生成了新的锁,而这个锁和我们程序里使用的所不是同一个,就没办法交互了。因此要把 mutex 对象设为引用,即起别名,这样所有的用同一个mutex 对象初始化 生成的 condition 对象交互的都是同一mutex 互斥锁,这就和我们缓冲区的操作相吻合, 不会出错。
b)在原生queue的上面封装了一层同步与互斥机制buffer, 这里的buffer实现了一个线程安全的缓冲区。之前生产者和消费者要对缓冲区队列进行的操作都封装到buffer中,这样在生产者类和消费者线程类中直接调用函数即可。此外buffer包含了mutexlock 对象和 condition对象,用于实现对缓冲区的同步与互斥访问,这与之前的操作一样。(关于同级函数不能加两次锁的问题,以consume函数为例,mutex枷锁后,在while循环中判空时也要加锁,这时上面的那个锁没释放,因而这边没法进行下去,结果就造成了死锁。)
c)生产者线程和消费者线程持有buffer的引用,因为多个线程要与同一个buffer 交互。这和condition中的 mutex 对象引用相同。
d)buffer 内置了同步与互斥机制,使得生产者进程和消费者进程不必关系竞态问题,这使得模块之间的独立性增强,这符合软件工程中的“高内聚 低耦合”原则。
2. 两组概念
2.1 一个类持有另一个类的引用,这叫做类的声明。一个类的数据成员含有另一个类的对象,这叫做类的组合。
2.2 使用了类的指针,引用,采用前向声明即可; 如果使用了类的对象,或者使用对象、指针。引用调用了数据成员或者函数, 此时必须使用头文件。
0715-----C++Primer听课笔记----------疯狂封装之生产者与消费者,布布扣,bubuko.com
0715-----C++Primer听课笔记----------疯狂封装之生产者与消费者
原文地址:http://www.cnblogs.com/monicalee/p/3847530.html