在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; }