三个生产者(整数入列)线程、两个消费者线程(出列打印)
队列为空:
消费线程要睡眠等待 --需要生产者唤醒
队列为满(规定只有十个存储空间):
生产者要睡眠等待 --需要消费者唤醒
其他获锁、出列或者入列:
code:
#include"link_queue.h"
#include
#include
#include
#include
#include
pthread_mutex_t mutex; //互斥锁
pthread_cond_t cond_full,cond_empty; //队列判满,判空 条件变量
lqueue_t *head; //初始化队列
int i=0;
void *producer(void *arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
//等待插入完毕 控制10个值 等待信号
while(i>=10)
{
pthread_cond_wait(&cond_full,&mutex);
}
sleep(random()%5);
int ret=random()%10;
link_enqueue(head,ret);
i++;
printf("pthread %u produce : %dn",pthread_self(),ret);
//等插入10个值之后发送读取信号 发送信号
if(i>=10)
pthread_cond_broadcast(&cond_empty);
pthread_mutex_unlock(&mutex);
pthread_yield();
}
}
void *consumer(void *arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
//读取控制条件 小于10之内都等待 等待信号
while(i<10)
{
pthread_cond_wait(&cond_empty,&mutex);
}
sleep(random()%5);
int ret=link_dequeue(head);
i--;
printf("pthread %u consumer done = %dn",pthread_self(),ret);
//发送写信号 在1-10之间发送读信号 发送信号
if(i>=0||i<10)
pthread_cond_broadcast(&cond_full);
pthread_mutex_unlock(&mutex);
pthread_yield();
}
}
int main() {
head=lqueue_init();
pthread_t thid[5];
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond_full,NULL);
pthread_cond_init(&cond_empty,NULL);
srand(time(0));
int i;
//创建5个线程 3个生产者,2个消费者
for(i=0;i<5;i++)
{
if(i>2)
{
pthread_create(&thid,NULL,consumer,NULL);
continue;
}
pthread_create(&thid,NULL,producer,NULL);
}
for(i=0;i<5;i++)
{
pthread_join(thid,NULL);
}
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond_full);
pthread_cond_destroy(&cond_empty);
return 0;
}
/*********************
***队列头文件****
************************/
#ifndef _LINK_QUEUE_H_
#define _LINK_QUEUE_H_
#ifdef _cplusplus
extern "C"
{
#endif
#include
typedef struct qnode{
int data;
struct queue *next;
}qnode_t;
typedef struct lqueue
{
qnode_t *front;
qnode_t *rear;
}lqueue_t;
lqueue_t *lqueue_init();
void link_enqueue(lqueue_t *qhead,int data); //添加数据
int link_dequeue(lqueue_t *qhead); //删除数据
int link_getqueue(lqueue_t *qhead); //获取数据
int lqueue_empty(lqueue_t *qhead); //队列判空
#ifdef _cplusplus
}
#endif
#endif
/*********************
***队列头源文件****
************************/
#include"link_queue.h"
#include
#include
lqueue_t *lqueue_init()
{
lqueue_t *head=(lqueue_t *)malloc(sizeof(lqueue_t));
assert(head!=NULL);
head->front=NULL;
head->rear=NULL;
return head;
}
void link_enqueue(lqueue_t *head,int data)
{
if(NULL==head)
return;
qnode_t *new_qnode=(qnode_t *)malloc(sizeof(qnode_t));
assert(new_qnode!=NULL);
new_qnode->next=NULL;
new_qnode->data=data;
if(lqueue_empty(head))
{
head->front=new_qnode;
head->rear=new_qnode;
}
else
{
head->rear->next=new_qnode;
head->rear=new_qnode;//yi dong rear
}
}
int link_dequeue(lqueue_t *head)
{ if(lqueue_empty(head))
return -999;
qnode_t *q=NULL;
int x=head->front->data;
q=head->front;
if(head->front==head->rear)
{ free(head->front);
head->front=NULL;
head->rear=NULL;
}
else
{
head->front=head->front->next;
free(q);
q=NULL;
}
return x;
}
int link_getqueue(lqueue_t *head)
{
if(lqueue_empty(head))
return -1;
else
return head->front->data;
}
int lqueue_empty(lqueue_t *head)
{ if(NULL==head)
return -1;
else if(head->front==NULL&&head->rear==NULL)
return 1;
else
return 0;
}
编译:gcc link_queue.c pro_con.c -lpthread
执行 :./a.out
0
|
|
|
|