在IPC系列文章当中,利用信号量集实现的是用户态下生产者-消费者模型的模型。本文以内核模块的方式,通过创建内核线程来为大家演示内核态下的生产者消费者模型。本模型属于np-nc-nb,即多个生产者多个消费着多个缓冲区。
在加载函数中,完成一些初始化的工作,并分别创建了5个生产者线程和消费者线程。kernel_thread函数的第一个参数是所所创建线程要做的动作;通过第二个参数传递i变量。
static int __init np_nc_init(void)
{
int i;
printk("np_nc module is working..\n");
in=out=0;
cflag=0;
init_MUTEX(&mutex);
sema_init(&s1,BUF_NUM);
sema_init(&s2,0);
for(i=0;i< N;i++)
{
index[i]=i+1;
kernel_thread(productor_thread,&(index[i]),CLONE_KERNEL);
kernel_thread(consumer_thread,&(index[i]),CLONE_KERNEL);
}
return 0;
}
在生产者函数中,PNUM是每个生产者要生产货物的数量。语句buf[in]=i*100+(PNUM-p_num+1)即是产生货物的过程。
int productor_thread(void *p)
{
int i=*(int *)p;
int p_num=PNUM;
while(p_num)
{
if((s1.count)<=0)
{
printk("[producer %d,%d]:I will be waiting for producting..\n",i,s1.count);
}
down(&s1);
down(&mutex);
buf[in]=i*100+(PNUM-p_num+1);
printk("[producer %d,%d]:I producted a goods \"%d\" to buf[%d]..\n",i,s1.count,buf[in],in);
in=(in+1)%BUF_NUM;
up(&mutex);
up(&s2);
p_num--;
}
return 0;
}
在消费者函数中,通过一个全局变量CNUM来控制消费者总共的消费次数。
int consumer_thread(void *p)
{
int i=*(int *)p;
int goods;
while(cflag!=CNUM)
{
if((s2.count)<=0)
{
printk("[consumer %d,%d]:I will be waiting for goods..\n",i,s2.count);
}
down(&s2);
down(&mutex);
goods=buf[out];
printk("[consumer %d,%d]:I consumed a goods \"%d\" from buf[%d]..\n",i,s2.count,goods,(out%BUF_NUM));
out=(out+1)%BUF_NUM;
up(&mutex);
up(&s1);
cflag++;
}
return 0;
}