多个生产者,单个消费者,只考虑生产者之间的同步互斥
#include"unpipc.h"
#defineMAXNITEMS1000000
#defineMAXNTHREADS100

intnitems;/**//*read-onlybyproducerandconsumer*/
struct
{
pthread_mutex_tmutex;//互斥信号量
intbuff[MAXNITEMS];
intnput;//下一个存放元素的下标
intnval;//下一个存放的值
}shared=
{PTHREAD_MUTEX_INITIALIZER};
void*produce(void*),*consume(void*);
int
main(intargc,char**argv)

{
inti,nthreads,count[MAXNTHREADS];
pthread_ttid_produce[MAXNTHREADS],tid_consume;
if(argc!=3)
err_quit("usage:prodcons2<#items><#threads>");
nitems=min(atoi(argv[1]),MAXNITEMS);//生产者存放的条目数
nthreads=min(atoi(argv[2]),MAXNTHREADS);//待创建的生产者线程数
Set_concurrency(nthreads);//通知线程系统我们希望并发多少线程
/**//*4startalltheproducerthreads*/
for(i=0;i<nthreads;i++)
{
count[i]=0;//计数器初始化为0
Pthread_create(&tid_produce[i],NULL,produce,&count[i]);//创建生产者线程
}

/**//*4waitforalltheproducerthreads*/
for(i=0;i<nthreads;i++)
{
Pthread_join(tid_produce[i],NULL);//等待生产者线程结束
printf("count[%d]=%d/n",i,count[i]);
}
//这样做的目的是为了避免生产者和消费者之间的同步问题,这里只考虑生产者之间的同步
/**//*4start,thenwaitfortheconsumerthread*/
Pthread_create(&tid_consume,NULL,consume,NULL);//创建消费者线程
Pthread_join(tid_consume,NULL);
exit(0);
}
/**//*endmain*/

/**//*includeproducer*/
void*
produce(void*arg)

{
for(;;)
{
Pthread_mutex_lock(&shared.mutex);
if(shared.nput>=nitems)
{//生产完毕
Pthread_mutex_unlock(&shared.mutex);
return(NULL);/**//*arrayisfull,we'redone*/
}
shared.buff[shared.nput]=shared.nval;
shared.nput++;
shared.nval++;
Pthread_mutex_unlock(&shared.mutex);
*((int*)arg)+=1;//每个线程私有的计数器,不需要加锁
}
}
void*
consume(void*arg)

{
inti;

for(i=0;i<nitems;i++)
{
if(shared.buff[i]!=i)
printf("buff[%d]=%d/n",i,shared.buff[i]);
}
return(NULL);
}
/**//*endproducer*/
生产者和消费者之间的同步,消费者采用的方式就是不断轮询。

#include"unpipc.h"
#defineMAXNITEMS1000000
#defineMAXNTHREADS100

intnitems;/**//*read-onlybyproducerandconsumer*/
struct
{
pthread_mutex_tmutex;
intbuff[MAXNITEMS];
intnput;
intnval;
}shared=
{PTHREAD_MUTEX_INITIALIZER};
void*produce(void*),*consume(void*);

/**//*includemain*/
int
main(intargc,char**argv)

{
inti,nthreads,count[MAXNTHREADS];
pthread_ttid_produce[MAXNTHREADS],tid_consume;
if(argc!=3)
err_quit("usage:prodcons3<#items><#threads>");
nitems=min(atoi(argv[1]),MAXNITEMS);
nthreads=min(atoi(argv[2]),MAXNTHREADS);

/**//*4createallproducersandoneconsumer*/
Set_concurrency(nthreads+1);
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);

/**//*4waitforallproducersandtheconsumer*/
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);
exit(0);
}
/**//*endmain*/
void*
produce(void*arg)

{
for(;;)
{
Pthread_mutex_lock(&shared.mutex);
if(shared.nput>=nitems)
{
Pthread_mutex_unlock(&shared.mutex);
return(NULL);/**//*arrayisfull,we'redone*/
}
shared.buff[shared.nput]=shared.nval;
shared.nput++;
shared.nval++;
Pthread_mutex_unlock(&shared.mutex);
*((int*)arg)+=1;
}
}

/**//*includeconsume*/
void
consume_wait(inti)

{
for(;;)
{
Pthread_mutex_lock(&shared.mutex);
if(i<shared.nput)
{
Pthread_mutex_unlock(&shared.mutex);
return;/**//*anitemisready*/
}
Pthread_mutex_unlock(&shared.mutex);
}
}
void*
consume(void*arg)

{
inti;

for(i=0;i<nitems;i++)
{
consume_wait(i);
if(shared.buff[i]!=i)
printf("buff[%d]=%d/n",i,shared.buff[i]);
}
return(NULL);
}
/**//*endconsume*/
每个条件变量都有一个互斥锁与之关联,调用pthread_cond_wait等待某个条件为真时,同时指定其条件变量的地址和所关联的互斥锁的地址
使用条件变量来通知,避免消费者轮询

/**//*includeglobals*/
#include"unpipc.h"
#defineMAXNITEMS1000000
#defineMAXNTHREADS100

/**//*globalssharedbythreads*/
intnitems;/**//*read-onlybyproducerandconsumer*/
intbuff[MAXNITEMS];
struct
{//用于生产者之间的同步
pthread_mutex_tmutex;
intnput;/**//*nextindextostore*/
intnval;/**//*nextvaluetostore*/
}put=
{PTHREAD_MUTEX_INITIALIZER};

struct
{//用于生产者和消费者之间同步
pthread_mutex_tmutex;
pthread_cond_tcond;
intnready;/**//*numberreadyforconsumer*/
}nready=
{PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER};
/**//*endglobals*/
void*produce(void*),*consume(void*);

/**//*includemain*/
int
main(intargc,char**argv)

{
inti,nthreads,count[MAXNTHREADS];
pthread_ttid_produce[MAXNTHREADS],tid_consume;
if(argc!=3)
err_quit("usage:prodcons6<#items><#threads>");
nitems=min(atoi(argv[1]),MAXNITEMS);
nthreads=min(atoi(argv[2]),MAXNTHREADS);
Set_concurrency(nthreads+1);
/**//*4createallproducersandoneconsumer*/
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);

/**//*waitforallproducersandtheconsumer*/
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);
exit(0);
}
/**//*endmain*/

/**//*includeprodcons*/
void*
produce(void*arg)

{
for(;;)
{
Pthread_mutex_lock(&put.mutex);
if(put.nput>=nitems)
{
Pthread_mutex_unlock(&put.mutex);
return(NULL);/**//*arrayisfull,we'redone*/
}
buff[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++;//置为1
Pthread_mutex_unlock(&nready.mutex);
*((int*)arg)+=1;
}
}
void*
consume(void*arg)

{
inti;

for(i=0;i<nitems;i++)
{
Pthread_mutex_lock(&nready.mutex);
while(nready.nready==0)
Pthread_cond_wait(&nready.cond,&nready.mutex);//wait条件变量
nready.nready--;//置为0
Pthread_mutex_unlock(&nready.mutex);
if(buff[i]!=i)
printf("buff[%d]=%d/n",i,buff[i]);
}
return(NULL);
}
/**//*endprodcons*/
本文探讨了多生产者单消费者的模型实现,通过不同同步机制如互斥锁和条件变量避免竞态条件,确保线程间正确协作。
1711

被折叠的 条评论
为什么被折叠?



