5.多线程:生产者/消费者 linux 下
/*
5.多线程:生产者/消费者
有两个线程,生产线程负责产生随机自然数(>0),每次产生一个,产生好后放入一个数组构成的缓冲区。消费线程负责取出来,显示在屏幕上。缓冲区的number字段为0时表示为该缓冲区为空闲;否则为忙状态。
当缓冲区都处于忙状态时,生产线程要等待缓冲区中有空闲缓冲区,即等待消费线程进行消费;当缓冲区都处于空闲状态时,消费线程要等待生产线程生产。
实现者必须体会这句话的含义,即条件变量。
缓冲区的记录定义如下:
struct node_st {
int number;
struct node_st *next;
};
typedef struct node_st node_st;
node_st pool[10]; /* 缓冲区个数为10个 */
要求:
1) 消费线程每取走一个自然数,则将该缓冲区置成0, 即将 node_st 的 number 字段置成0
2) 生成线程检验缓冲区是否为空的依据是判断node_st 的 number 字段是否为0
3) 不容许生产线程和消费线程同时访问缓冲区
4) 使用 mutex, semaphore 等 线程同步对象,通信对象
5) 不能使用 Sleep 等函数来同步线程,但可以使用Sleep来调节生产或消费的速度。
6) 使用VC的 console 工程,将生产线程产生的自然数和消费线程消费的自然数输出在屏幕上。
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
struct node_st
{
int number;
struct node_st * next;
};
typedef struct node_st node_st;
node_st * head;
pthread_mutext_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
node_st * initalizing()
{
node_st * r;
node_st * pointer ;
int i;
head=r=(node_st *)malloc(sizeof(node_st));
head->number=0;
for(i=1; i<=10; i++)
{
pointer=(node_st *)malloc(sizeof(node_st));
pointer->number=0;
r->next=pointer;
r=pointer;
}
r->next=NULL;
return head;
}
void print(node_st * head)
{
node_st * tmp;
tmp = head;
while(tmp->next!=NULL)
{
printf("%d \r\n",tmp->number);
tmp=tmp->next;
}
}
void * pro(void *)
{
int i=0;
node_st * tmp;
while(1)
{
tmp = head;
int num=rand ()*10;
while(num ==0)
num=rand ()*10;
pthread_mutex_lock(&mutex);
while(tmp->number>0)
{
if(tmp->next==NULL)
tmp = tmp->next;
i++;
}
if(i == 0)
pthread_cond_broadcast(&cond);
if(i == 10)
pthread_cond_wait(&cond,&mutex);
tmp->number=num;
printf("Product %d\r\n",tmp->number);
pthread_mutex_unlock(&mutex);
}
}
void *con(void *)
{
node_st * tmp;
node_st * r;
int i = 0;
while(1)
{
tmp = head;
pthread_mutex_lock(&mutex);
while((tmp->number > 0)&&(tmp->next!=NULL))
{
r=tmp;
tmp = tmp->next;
}
if(i == 10)
pthread_cond_broadcast(&cond);
if(i == 0)
pthread_cond_wait(&cond,&mutex);
printf("Consume %d\r\n",r->number);
r->number=0;
pthread_mutex_unlock(&mutex);
}
}
/*
void deleteall(node_st * head)
{
node_st * tmp =head;
while(tmp->next!=NULL)
{
head=tmp->next;
delete tmp;
tmp=head;
}
delete head;
}
*/
int main(int argc,char **args)
{
pthread_t product;
pthread_t consume;
head=initalizing();
pthread_create(&product,NULL,pro,NULL);
pthread_create(&consume,NULL,con,NULL);
pthread_join(product,NULL);
pthread_join(consume,NULL);
return 0;
}