生产者消费者问题

#include 
#include 
#include 

#define MAX_BUF_NUM 10000
#define MAX_PRO_NUM 10
#define MAX_CON_NUM 1

typedef struct bounded_buf_tag
{
	int buf[MAX_BUF_NUM];
	pthread_mutex_t lock;
	pthread_cond_t cond;
	int cur;
}bounded_buf_t;


bounded_buf_t shareBuf;


int Init(bounded_buf_t *b)
{
	if( b == NULL )
	{
		return -1;
	}

	b->cur = 0;
	//b->lock = PTHREAD_MUTEX_INITIALIZER;
	//b->cond = PTHREAD_COND_INITIALIZER;
	memset(b->buf, -1, sizeof(int)*MAX_BUF_NUM);

	return 0;
}

void *consumer(void *arg)
{
	while(1)
	{
		pthread_mutex_lock(&(shareBuf.lock));

		int cur_read = (shareBuf.cur - 1);
		
		if( cur_read < 0 )
		{
			pthread_cond_wait(&(shareBuf.cond), &(shareBuf.lock));
			continue;
		}

		fprintf(stderr, "%lu read %d at %d\n", pthread_self(), shareBuf.buf[cur_read], cur_read);

		if( cur_read >= 0 )
		{
			shareBuf.buf[cur_read] = -1;

			shareBuf.cur--;
		}

		pthread_mutex_unlock(&(shareBuf.lock));
	}
}

void *producer(void *arg)
{
	while(1)
	{
		pthread_mutex_lock(&(shareBuf.lock));

		if( shareBuf.cur >= MAX_BUF_NUM )
		{
			pthread_mutex_unlock(&(shareBuf.lock));
			pthread_cond_broadcast(&(shareBuf.cond));
			continue;
		}
		
		if( shareBuf.cur < 0 )
		{
			shareBuf.cur = 0;
		}

		shareBuf.buf[shareBuf.cur] = shareBuf.cur;
		fprintf(stderr, "%lu write %d at %d\n", pthread_self(), shareBuf.buf[shareBuf.cur], shareBuf.cur);
		shareBuf.cur++;
		
		pthread_mutex_unlock(&(shareBuf.lock));
		
		pthread_cond_broadcast(&(shareBuf.cond));
		
	}
}

int main()
{
	Init(&shareBuf);
	
	pthread_t pid_pro, pid_con;

	pthread_setconcurrency(MAX_PRO_NUM + MAX_CON_NUM);

	int i;
	for( i=0; i


1.为什么是只需要一个信号量?
因为只有一个共享数据要保护。
在这里,我们把共享数据区buf[]当做一个整体来看待。
我们对该数据去进行的读写操作规则是:在进行读操作时不能写。在写时不能进行读。也就是读写是互斥的。所以我们只需要一个互斥量。


2.信号量的使用原则是什么
信号量使用的原则是:
1.信号量的数量要尽量少,因为信号量越多,线程之间的执行速度越慢(因为相互阻塞)。所以信号量保护的临界区要尽量大,以尽量减少信号量的使用数量
2.如果信号量保护的临界区频繁访问,而临界区又很大,导致某个线程长时间的占用处理器。这时要增加信号量来切割临界区,以减少单个线程对处理器的占用。


所以我们在设计多线程程序时要考虑线程的执行速度以及临界区的大小,酌情的使用信号量,在速度和信号量数量之间取得一个平衡。


3.如何确定信号量的具体使用个数
根据共享数据的个数和数据结构来决定。
信号量设计出来的目的时保护共享数据。对共享数据的操作(读和写)方式以及要保护的共享数据的个数决定了互斥量的个数。
举个例子来说,保护一个链表,需要一个信号量就够了。因为每次对链表的读写操作都是通过表头进行的。我们只需要保护表头地址。
但是要保护一个队列我们就需要两个互斥锁:一个保护队列头,一个保护队列尾。

你可能感兴趣的:(multithread,architeture)