吸烟者问题是为了解决“可以生产多个产品的单生产者”问题提供了一个思路。
问题描述:有三个抽烟者和一个供应者。每个抽烟者不停地卷烟抽,组成一根烟需要三种材料:烟草、纸和胶水。三个抽烟者中,第一个有烟草,第二个有纸,第三个拥有胶水。供应者无限地提供三种材料,供应者每次将两种材料放到桌子上,拥有剩下那种材料的抽烟者卷一根烟并抽掉它,并给供应者一个信号告诉已完成,那么供应者可以继续提供另外两种材料,如此重复(让三个抽烟者轮流地抽烟)。
问题分析:
- 关系分析。供应者与三个抽烟者分别是同步关系。供应着无法同时满足两个或两个以上的抽烟者,所以三个抽烟者是互斥关系。
- 整理思路。这里有四个进程,一个供应者,三个抽烟者。
- 信号量设置。信号量offer1,offer2,offer3分别表示烟草和纸的组合、烟草和胶水的组合、纸和胶水的组合。信号量finish用于互斥进行抽烟动作。
代码描述如下:
- int i=0;
- semaphore offer1=0;//定义信号量对应烟草和纸的组合
- semaphore offer2=0;//定义信号量对应烟草和胶水的组合
- semaphore offer3=0;//定义信号量对应纸和胶水的组合
- semaphore finish=0;//定义信号量表示抽烟是否完成
- process P1(){
- if(i==0)
- V(offer1); //提供烟草和纸
- else if(i==1)
- V(offer2);//提供烟草和胶水
- else if(i==2)
- V(offer3);//提供纸和胶水
- 任意两种材料放在桌子上;
- P(finish);
- i=(i+1)%3;
- }
- process P2(){//拥有烟草者
- while(1){
- P(offer3);
- 拿纸和胶水,卷成烟,抽掉
- V(finish);
- }
- }
- process P3(){//拥有纸者
- while(1){
- P(offer2);
- 拿烟草和胶水,卷成烟,抽掉
- V(finish);
- }
- }
- process P4(){//拥有胶水者
- while(1){
- P(offer1);
- 拿烟草和纸,卷成烟,抽掉
- V(finish);
- }
- }
其实吸烟者问题还是比较好理解的,不过要确认的是这里供应者一次是供应两种,那么就把它看成一种组合就行。