进程同步问题
生产者消费者问题
描述
这是一个多进程并发协作的问题(也可以是多线程),在这里我们涉及到了两类进程,一类是生产者进程,一类是消费者进程,生产者用于生产数据,消费者用于处理生产者生产的数据,所有消费者处理的数据必须由生产者生产得到。
为了解耦这两类进程之间的关系,我们引入一个数据缓冲池,这个缓冲池用于存储数据。生产者将数据产生后投入这个缓冲池中,消费者直接由这个缓冲池中取出数据,这样就不必考虑这两个进程之间的相关依赖,即(解耦)。两个进程只需对缓冲区进行操作即可。生产者只有在缓冲区没有填满时才能继续生产,否则就会被阻塞,消费者只有在缓冲区中还有数据时才能对里面的数据进行操作,如果缓冲区为空,那么将没有数据供消费者处理,生产者进程会被阻塞。而且两个进程对缓冲区的访问可能是阻塞的(即缓冲池是临界资源)。
图中P是生产者,C是消费者。
先整理一下语义:缓冲不为空时消费者可以去数据处理,缓冲没有满时,生产者可以生产数据存入缓冲中。对缓冲的操作是阻塞访问。
int full=0;//表示消费者可用的空间
int empty=n;//表示生产者可用的空间
//初始状态缓冲区全为空
int visit=1;//对缓冲的访问
//---------------上面全是信号量----------------
Resuouse buf[n];//缓冲的空间
int in=0;//生产者对buf的访问指针
int out=0;//消费者对buf的访问指针
//初始状态都为0
接下来就是对于原语的一个伪代码描述
wait(int &s)
{
s--;
if(s<0)//S<0表示没有可以的资源则将其对应当前进程进行阻塞等待
{
block();
}
}
signal(int &s)
{
s++;
if(s<=0)//释放使用的资源之后检查是否还有进程在申请,如果有就从队列中唤醒。
{
wakeup(list);//list为被阻塞的进程队列
}
}
由于这里的信号量所描述的都是大于零时可以访问,所以其原语对应操作相同。
接下来就是生产者与消费者的伪代码描述
Producer()
{
while(true)
{
wait(empty);//保证缓冲区有空余空间
wait(visit);//保证对缓冲资源的阻塞式访问
buf[in]=data;//生产出相应数据
in=