#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXTHREADS 50
#define MAXITEMS 8192
struct{
pthread_mutex_t mutex;
int buff[MAXITEMS];
int nput; //当前索引
int nval;
}shareobject = {PTHREAD_MUTEX_INITIALIZER} ;
//生产者线程
static void * producer(void * p)
{
int nitems = *(int*)p;
while(1){
pthread_mutex_lock(&shareobject.mutex);
//如果生产完成 则退出 退出线程前 unlock
if(shareobject.nput >= nitems){
pthread_mutex_unlock(&shareobject.mutex);
break;
}
shareobject.buff[shareobject.nput++] = shareobject.nval++;
pthread_mutex_unlock(&shareobject.mutex);
}
}
//消费者
static void * consumer(void * p)
{
int nitems = *(int*)p;
// 由于消费者只有一个线程 则总共需要检测 nitems 次数
for(int i = 0 ; i < nitems;++i){
//首先确认当前要检测的索引 是生产者已经生产的
while(1){
pthread_mutex_lock(&shareobject.mutex);
// 只有当 nput 的索引大于 i 则表示生产者已经完成 i 次操作
if(i < shareobject.nput){
// 其实也可以把下面 if 语句移动到这里.不过这样更好. 让关键段中的代码少点.
pthread_mutex_unlock(&shareobject.mutex);
break;
}
pthread_mutex_unlock(&shareobject.mutex);
}
if(shareobject.buff[i] != i)
printf("error : buff[%d] = %d\n" , i,shareobject.buff[i]);
}
}
int main(int argc ,char ** argv)
{
if( argc != 3){
puts("nitems nthreads");
return 0;
}
//nitems 放置n条数据
int nitems = atoi(argv[1]);
nitems = nitems > MAXITEMS ? MAXITEMS : nitems;
//N 个生产线程
int nthread = atoi(argv[2]);
if(nthread > MAXTHREADS)
nthread = MAXTHREADS;
pthread_t tid_p[MAXTHREADS] , tid_c;
//并发 +1 个消费者线程
pthread_setconcurrency(nthread + 1);
//生产者线程
for(int i = 0; i < nthread; ++i)
pthread_create(&tid_p[i],NULL,producer,&nitems);
//消费者
pthread_create(&tid_c,NULL,consumer,&nitems);
for(int i = 0; i < nthread;++i)
pthread_join(tid_p[i],NULL);
pthread_join(tid_c,NULL);
return 0;
}