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

Posted z354681250

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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]生产者与消费者 三种模型 C的主要内容,如果未能解决你的问题,请参考以下文章

[Linux 高并发服务器]生产者与消费者模型

Linux篇第十五篇——多线程(生产消费模型+POSIX信号量)

Linux篇第十五篇——多线程(生产消费模型+POSIX信号量)

Linux生产者消费者模型

Linux线程同步与互斥/生产消费者模型

C++11多线程编程——生产消费者模型之条件变量