问题描述:一组生产者向一组消费者提供消息,它们共享一个有界缓冲池,生产者向其中投放消息,消费者从中取得消息。假定这些生产者和消费者互相等效,只要缓冲池未满,生产者可将消息送入缓冲池;只要缓冲池未空,消费者可从缓冲池取走一个消息。
功能要求:根据进程同步机制,编写一个解决上述问题的程序,可显示缓冲池状态、放数据、取数据等过程。
首先使用链表的方法来编写代码:
#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;
}