#include<stdio.h>
#include<pthread.h>
#include <semaphore.h>
#include<stdlib.h>
//#define SIZE 10
typedef struct Node
{
int data;
struct Node* next;
}Node,**ppNode;
static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
Node* pHead=NULL;
Node* GetNode(int x)
{ Node* tmp=(Node*)malloc(sizeof(Node));
if(tmp==NULL)
{
perror("malloc");
return NULL;
}
tmp->data=x;
tmp->next=NULL;
return tmp;
}
void InitList(ppNode p)
{
*p=GetNode(0);
}
void PushFront(Node* pHead,const int x)
{
Node* tmp=GetNode(x);
tmp->next=pHead->next;
pHead->next=tmp;
}
void PopFront(Node* pHead,int* out)
{
Node* tmp=pHead->next;
if(tmp)
{
Node* next=tmp->next;
pHead->next=next;
*out=tmp->data;
free(tmp);
tmp=NULL;
}
}
void* product(void* arg)
{
while(1)
{
int data=rand()%1000;
pthread_mutex_lock(&lock);
PushFront(pHead,data);
pthread_mutex_unlock(&lock);
pthread_cond_signal(&cond);
printf("product done:%d\n",data);
sleep(1);
}
}
void* consume(void* arg)
{
while(1)
{
int c=-1;
pthread_mutex_lock(&lock);
while(pHead->next==NULL)
{
printf("consume is waiting!\n");
pthread_cond_wait(&cond,&lock);
}
PopFront(pHead,&c);
pthread_mutex_unlock(&lock);
printf("consume is done: %d\n",c);
}
}
int main()
{
InitList(&pHead);
pthread_t p;
pthread_t c;
pthread_create(&p,NULL,product,NULL);
pthread_create(&c,NULL,consume,NULL);
pthread_join(p,NULL);
pthread_join(c,NULL);
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&cond);
return 0;
}
环形队列实现原理图:
环形队列实现规则: (1)生产者优先:其实就算消费者优先,由于刚开始没有生产出数据,消费者也会被挂起; (2)消费者永远不能追上消费者:试想一下如果消费者追上生产者或者超过消费者的时候,此时消费者消费的并不是生产者实际所生产出的数据,而属于垃圾数据; (3)生产者不能将消费者包一圈:这个也很好理解,如果生产者允许将消费者包一圈的话,那就相当于生产者可以无限的生产,并不停的覆盖掉原来所产生的数据,那么如果原来生产出的数据中如果有的是消费者需要获取的数据,那么除了生产者在次生产出该数据外,消费者将再也不能得到所想要的数据; //环形队列实现代码:
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#define SIZE 10
int Ring[SIZE]={0};
sem_t DataSem; //数据信号量
sem_t BlankSem; //空格信号量
void* consume(void* arg)
{
int i=0;
int data;
while(1)
{
sem_wait(&DataSem); //阻塞等待
data= Ring[i++];
sem_post(&BlankSem);
i%=SIZE;
printf("consume: %d\n",data);
sleep(1);
}
}
void* product(void* arg)
{
int i=0;
int data;
while(1)
{
sem_wait(&BlankSem);
Ring[i++]=data;
sem_post(&DataSem);
printf("product: %d\n",data++);
i%=SIZE;
}
// sleep(1);
}
int main()
{
pthread_t p,c;
sem_init(&BlankSem,0,SIZE);
sem_init(&DataSem,0,0);
pthread_create(&c,NULL,consume,NULL);
pthread_create(&p,NULL,product,NULL);
pthread_join(c,NULL);
pthread_join(p,NULL);
sem_destroy(&BlankSem);
sem_destroy(&DataSem);
return 0;
}
//多线程版本实现
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#define SIZE 10
int Ring[SIZE]={0};
sem_t DataSem; //数据信号量
sem_t BlankSem; //空格信号量
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
void* consume(void* arg)
{
static int i=0;
int data;
while(1)
{
sem_wait(&DataSem); //阻塞等待
pthread_mutex_lock(&mutex);
data= Ring[i++];
sem_post(&BlankSem);
i%=SIZE;
printf("consume: %d\n",data);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
void* product(void* arg)
{
int i=0;
int data;
while(1)
{
sem_wait(&BlankSem);
pthread_mutex_lock(&mutex);
Ring[i++]=data;
sem_post(&DataSem);
printf("product: %d\n",data++);
i%=SIZE;
pthread_mutex_unlock(&mutex);
sleep(2);
}
}
int main()
{
pthread_t p1,p2,c1,c2;
sem_init(&BlankSem,0,SIZE);
sem_init(&DataSem,0,0);
pthread_create(&c1,NULL,consume,NULL);
pthread_create(&c2,NULL,consume,NULL);
pthread_create(&p1,NULL,product,NULL);
pthread_create(&p2,NULL,product,NULL);
pthread_join(c1,NULL);
pthread_join(c2,NULL);
pthread_join(p1,NULL);
pthread_join(p2,NULL);
sem_destroy(&BlankSem);
sem_destroy(&DataSem);
return 0;
}