【Linux】中的生产者与消费者的关系

问题描述:一组生产者向一组消费者提供消息,它们共享一个有界缓冲池,生产者向其中投放消息,消费者从中取得消息。假定这些生产者和消费者互相等效,只要缓冲池未满,生产者可将消息送入缓冲池;只要缓冲池未空,消费者可从缓冲池取走一个消息。 

功能要求:根据进程同步机制,编写一个解决上述问题的程序,可显示缓冲池状态、放数据、取数据等过程。 

首先使用链表的方法来编写代码:

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

typedef struct Node//定义一个Node的结构体
{
	int val;
	struct Node* next;
}Node_t,*Node_p,**Node_pp;

Node_p head = NULL;
Node_p allocNode(int Val)
{
	Node_p ret = (Node_p)malloc(sizeof(Node_t));
	ret->val=Val;
	ret->next=NULL;
	return ret;
}

void freeNode(Node_p del)//清空链表
{
	free(del);
}

int initList(Node_pp _head)//初始化链表
{
	*_head = allocNode(0);//对头结点初始化
	if(*_head == NULL)//如果头结点为空,直接返回
	{
		return 0;
	}
	return -1;//如果头结点不为空,返回-1
}

int Empty(Node_p _head)
{
	return (_head->next=NULL?0:-1);
}

int PopNode(Node_p _head,int *Val)
{
	if(Empty(_head) == 0)
	{
		return -1;
	}
	Node_p del = _head->next;
	*Val = del->val;
	freeNode(del);
	del = NULL;
	return 0;
}

void PrintList(Node_p _head)
{
	Node_p tmp = _head->next;
	while(tmp)
	{
		printf("%d",tmp->val);
		tmp=tmp->next;
	}
	printf("\n");
}

void Destroy(Node_pp _head)
{
	while(Empty(*_head)<0)
	{
		int tmp;
		PopNode(*_head,&tmp);
	}
	freeNode(*_head);
	*_head = NULL;
}

void *consumer(void *arg)
{
	while(1)
	{
		pthread_mutex_lock(&lock);
		int _val = rand()%1024;
		PushNode(head,_val);
		printf("consumer push done:%d \n",_val);
		sleep(1);
		pthread_mutex_unlock(&lock);
		pthread_cond_signal(&cond);
	}
	return NULL;
}

void *producter(void *arg)
{
	while(1)
	{
		pthread_mutex_lock(&lock);
		if(Empty(head)==0)
		{
			printf("producter check\n");
			pthread_cond_wait(&cond,&lock);
		}
		else
		{
			int _val;
			PopBNode(head,&_val);
			printf("producter pop done : %d\n",_val);
		}
		sleep(1);
		pthread_muyex_unlock(&lock);
	}
}

int main()
{
	initList(&head);
	pthread_t c,p;
	pthread_creat(&c,NULL,consumer,NULL);
	pthread_creat(&p,NULL,producter,NULL);

	pthread_join(c,NULL);
	pthread_join(p,NULL);
	DestroyList(&head);
	pthread_mutex_destroy(&lock);
	pthread_cond_destroy(&cond);
	return 0;
}
接下来实现一下环形队列的生产者和消费者:

#include<stdio.h>
#include<semaphore.h>
#include<pthread.h>
#include<unistd.h>
#include<stdlib.h>

#define _SIZE_	 64
int Buf[_SIZE_];
sem_t semBlank;//定义格子
sem_t semData;//定义格子里面的数据
sem_t proLock;//生产者之间的互斥
sem_t conLock;//消费者之间的互斥

void *Consumer(void *arg)//定义消费者
{
	pthread_detach(pthread_self());
	static int i = 0;
	int id=(int)arg;
	while(1)
	{
		usleep(1000);
		sem_wait(&semData);
		sem_wait(&conLock);

		printf("消费者%d消费了:%d,tid: %1u\n",id,Buf[i++],pthread_self());
		i%= _SIZE_;
		sem_post(&conLock);
		sem_post(&semBlank);
	}
}

void *Producter(void *arg)//定义生产者
{
	pthread_detch(pthread_self());
	static int i = 0;
	int id=(int)arg;
	while(1)
	{
		sleep(1);
		sem_wait(&semBlank);//对临界区数据进行p操作
		sem_wait(&proLock);//对生产者互斥锁进行P操作
		int num = rand()%10;
		Buf[i+1]=num;
		prntf("生产者%d生产了:%d,tid:%1u\n",id,num,pthread_self());
		i%= _SIZE_;

		sem_post(&proLock);//对生产者互斥锁进行v操作
		sem_post(&semData);//对临界区资源进行v操作
	}
}

int main()
{
	pthread_t con0,con1,pro0,pro1;
	sem_init(&semData,0,0);
	sem_init(&semBlank,0,_SIZE_);
	sem_init(&proLock,0,1);
	sem_init(&conLock,0,1);

	int i=0;
	pthread_creat(&pro0,NULL,Producter,(void*)i);
	pthread_creat(&con0,NULL,Consumer,(void*)i);
	i=1;
	pthread_creat(&pro1,NULL,Producter,(void*)i);
	pthread_creat(&con1,NULL,Consumer,(void*)i);

	sem_destroy(&semBlank);
	sem_destroy(&semData);
	pthread_join(pro0,NULL);
	pthread_join(con0,NULL);
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值