[Linux]生产者与消费者 三种模型 C

“生产者/消费者”问题描述:

有一个有限缓冲区和两个线程:生产者和消费者。他们分别把产品放入缓冲区和从缓冲区中拿走产品。当一个生产者在缓冲区满时必须等待,当一个消费者在缓冲区空时也必须等待。


1.      单锁模型


#include"stdio.h"
#include"pthread.h"

int buffer[10];
int top = 0;
int itime = 0;
int itime2 = 0;

pthread_t thread[2];
pthread_mutex_t mut;

void producer()
{
	while(1)
	{
		if(itime == 10) return;
		pthread_mutex_lock(&mut);
		if(top == 10)
		{
			printf("buffer is full...producer is waiting...\n");
			pthread_mutex_unlock(&mut);
			continue;
		}
		printf("pruducter set the %d\n", itime);
		top++;
		itime++;
		pthread_mutex_unlock(&mut);
	}
}


void consumer()
{
	while(1)
	{
		if(itime2 == 10) return;
		pthread_mutex_lock(&mut);
		if(top == 0)
		{
			printf("buffer is empty...consumer is waiting...\n");
			pthread_mutex_unlock(&mut);
			continue;
		}
		printf("consumer get the %d\n", itime2);
		top--;
		itime2++;
		pthread_mutex_unlock(&mut);
	}
}

int main()
{
	pthread_create(&thread[0], NULL, (void*)(&producer), NULL);	
	pthread_create(&thread[1], NULL, (void*)(&consumer), NULL);	
	
	sleep(1);
	return 0;
}


运行结果

buffer is empty...consumer is waiting...
buffer is empty...consumer is waiting...
buffer is empty...consumer is waiting...
pruducter set the 0
pruducter set the 1
pruducter set the 2
pruducter set the 3
pruducter set the 4
pruducter set the 5
pruducter set the 6
pruducter set the 7
pruducter set the 8
pruducter set the 9
consumer get the 0
consumer get the 1
consumer get the 2
consumer get the 3
consumer get the 4
consumer get the 5
consumer get the 6
consumer get the 7
consumer get the 8
consumer get the 9

分析

容易出现极端状况,一开始一直是consumer加锁,producer无法提供;不久后producer终于得到加锁,存入了10个货物,而后consumer取得10个货物。


 2. 两个互斥锁



#include"stdio.h"
#include"pthread.h"

int buffer[10];
int top = 0;
int itime = 0;
int itime2 = 0;

pthread_t thread[2];
pthread_mutex_t mut;
pthread_mutex_t mut2;

void producer()
{
	while(1)
	{
		if(itime == 10) return;
		pthread_mutex_lock(&mut);
		if(top == 10)
		{
			printf("buffer is full...producer is waiting...\n");
			pthread_mutex_unlock(&mut2);
			continue;
		}
		printf("pruducter set the %d\n", itime);
		top++;
		itime++;
		pthread_mutex_unlock(&mut2);
	}
}


void consumer()
{
	while(1)
	{
		if(itime2 == 10) return;
		pthread_mutex_lock(&mut2);
		if(top == 0)
		{
			printf("buffer is empty...consumer is waiting...\n");
			pthread_mutex_unlock(&mut);
			continue;
		}
		printf("consumer get the %d\n", itime2);
		top--;
		itime2++;
		pthread_mutex_unlock(&mut);
	}
}

int main()
{
	pthread_create(&thread[0], NULL, (void*)(&producer), NULL);	
	pthread_create(&thread[1], NULL, (void*)(&consumer), NULL);	
	
	sleep(1);
	return 0;
}

运行结果

buffer is empty...consumer is waiting...
pruducter set the 0
consumer get the 0
pruducter set the 1
consumer get the 1
pruducter set the 2
consumer get the 2
pruducter set the 3
consumer get the 3
pruducter set the 4
consumer get the 4
pruducter set the 5
consumer get the 5
pruducter set the 6
consumer get the 6
pruducter set the 7
consumer get the 7
pruducter set the 8
consumer get the 8
pruducter set the 9
consumer get the 9

很完美对不对?生产者生产一个就把自己锁起来,消费者消费一个后解锁生产者,把自己锁起来,生产者继续生产,循环反复。互斥锁的确能很好的实现进程/线程之间的同步问题,但是它是通过锁机制来实现的,就是仅仅通过加锁和解锁实现同步,效率比较低。


3. 利用条件变量

#include"stdio.h"
#include"pthread.h"

int buffer[10];
int top = 0;
int itime = 0;
int itime2 = 0;

pthread_t thread[2];
pthread_mutex_t mut;
pthread_cond_t con, con2;

void producer()
{
	while(1)
	{
		if(itime == 10) return;
		pthread_mutex_lock(&mut);
		if(top == 10)
		{
			printf("buffer is full...producer is waiting...\n");
			pthread_cond_wait(&con, &mut);
		}
		printf("pruducter set the %d\n", itime);
		top++;
		itime++;
		pthread_cond_signal(&con2);
		pthread_mutex_unlock(&mut);
		sleep(1);
	}
}


void consumer()
{
	while(1)
	{
		if(itime2 == 10) return;
		pthread_mutex_lock(&mut);
		if(top == 0)
		{
			printf("buffer is empty...consumer is waiting...\n");
			pthread_cond_wait(&con2, &mut);
		}
		printf("consumer get the %d\n", itime2);
		top--;
		itime2++;
		pthread_cond_signal(&con);
		pthread_mutex_unlock(&mut);
		sleep(1);
	}
}

int main()
{
	pthread_create(&thread[0], NULL, (void*)(&producer), NULL);	
	pthread_create(&thread[1], NULL, (void*)(&consumer), NULL);	
	
	sleep(10);
	return 0;
}


运行结果

buffer is empty...consumer is waiting...
pruducter set the 0
consumer get the 0
buffer is empty...consumer is waiting...
pruducter set the 1
consumer get the 1
buffer is empty...consumer is waiting...
pruducter set the 2
consumer get the 2
buffer is empty...consumer is waiting...
pruducter set the 3
consumer get the 3
pruducter set the 4
consumer get the 4
pruducter set the 5
consumer get the 5
pruducter set the 6
consumer get the 6
pruducter set the 7
consumer get the 7
pruducter set the 8
consumer get the 8
pruducter set the 9
consumer get the 9


结果还算比较正常,理解一下变量的使用。消费者发现缓冲区没有东西,通过条件变量把自己锁住;生产者生产并激活消费者;消费者从缓冲区消费;当生产者发现缓冲区满的时候,通过条件变量把自己锁住,消费者消费并重新激活生产者。如此。


你可能感兴趣的:(Linux)