Alex正在电脑前面作冥思苦想状,这时Tony悄悄地走到Alex的身后,观察了一会儿…
Tony : 看来今天我们要讨论同步问题了。
Alex : (惊奇地回头)。Hey Man , you scared me! 你说的没错,我正在学习同步这一块儿呢,有什么高见不妨说出来吧,我洗耳恭听!
Tony : 不敢不敢。关于进程和线程同步的问题,W. Richard Stevens在他的那本经典的“UNIX Network Programming Volume 2”中有过详尽的讲解,你不妨仔细阅读一下。
Alex : 远水解不了近渴。你还是大概跟我说说吧!
Tony : OK, 我们就拿一个最简单例子来探讨一下吧。在拿出例子之前我们来回顾一下同步的由来。Alex你说说为什么要同步呢?
Alex : 有共享就要同步,就好比超市的POS,如果没有好的同步顾客活动的策略,那超市不就乱了套了么,大家都争着抢着去结账。
Tony : 嗯,没错。mess world is not what we need! 互斥和条件变量是我们经常使用的同步手段,当然更高级的还有信号灯等。
Alex : 逐一说明吧,看来今天又会有不小的收获^_^
Tony : 历史上有个特别有名的问题叫做“生产者-消费者”问题,又叫“有限缓冲区”问题,我们今天的例子大约就是这个样子的。
Alex : (入迷的样子)
Tony : 我们的例子是这样的,我们有“生产者”和“消费者”两个角色,他们共享某一整型变量,规定如下:
1)生产者发现产品已经被消费了,便生产,即将该共享变量置为1;
2)消费者发现有产品了,便消费,即将该共享变量置为0;
很简单吧。我们还是用老办法,由简入难,我们可以使用最简单的手段“互斥锁”来完成这个任务。
Alex : 我知道“互斥锁”,但是了解得并不深,先讲讲理论把!
Tony : 互斥,顾名思义互相排斥,它是最基本的同步手段,一般用来保护“临界区”,“临界区”是一段代码,看起来互斥保护了临界区这段代码的,实质上互斥保护的是“临界区”中被操纵的数据。
Alex : 互斥是不是即可用于线程,也可以用于进程呢?
Tony : 都可以,在我们的例子中我们使用线程,因为线程间共享一个数据空间,实现起来比较容易;进程间要想共享数据就需要额外的支持,比如共享内存等。
Alex : 噢。
Tony : 我们开始吧,按照例子中所述我们应该有两个线程,分别代表生产者和消费者。按照W. Richard Stevens的指导,我们将我们的互斥锁和我们的共享数据放在一个结构体内。
...