#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAXITEMS 10000
#define MAXTHREADS 20
int nitems;
int buf[MAXITEMS];
struct
{
pthread_mutex_t mutex;
int nput;
int nval;
}put = {PTHREAD_MUTEX_INITIALIZER};
struct
{
pthread_mutex_t mutex;
pthread_cond_t cond;
int nready;
}nready = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER};
int min(int lhs, int rhs)
{
return lhs > rhs ? rhs:lhs;
}
void *produce(void *arg)
{
while(1)
{
pthread_mutex_lock(&put.mutex);
if(put.nput >= nitems)
{
pthread_mutex_unlock(&put.mutex);
return NULL;
}
buf[put.nput] = put.nval;
put.nput++;
put.nval++;
pthread_mutex_unlock(&put.mutex);
pthread_mutex_lock(&nready.mutex);
if(nready.nready == 0)
pthread_cond_signal(&nready.cond);
nready.nready++;
pthread_mutex_unlock(&nready.mutex);
*((int *)arg) += 1;
}
}
void *consume(void *arg)
{
int i;
for(i = 0; i <= nitems; i++)
{
pthread_mutex_lock(&nready.mutex);
while(nready.nready == 0)
{
pthread_cond_wait(&nready.cond, &nready.mutex);//pthread_cond_wait()先解锁,再阻塞,返回时再加锁
}
nready.nready--;
pthread_mutex_unlock(&nready.mutex);
if(buf[i] != i)
printf("buf[%d] = %d\n", i, buf[i]);
}
return NULL;
}
int main(int argc, char **argv)
{
int i, nthreads, count[MAXITEMS];
pthread_t tid_produce[MAXTHREADS], tid_consume;
if(argc != 3)
{
perror("argc error\n");
exit(0);
}
nitems = min(atoi(argv[1]), MAXITEMS);
nthreads = min(atoi(argv[2]), MAXTHREADS);
pthread_setconcurrency(3);
for(i = 0; i < nthreads; i++)
{
count[i] = 0;
pthread_create(&tid_produce[i], NULL, produce, &count[i]);
}
pthread_create(&tid_consume, NULL, consume, NULL);
for(i = 0; i < nthreads; i++)
{
pthread_join(tid_produce[i], NULL);
printf("count[%d] = %d\n", i, count[i]);
}
pthread_join(tid_consume, NULL);
return 0;
}