在操作系统中讲到进程同步的问题的时候,都会讲一些经典的例子,其中最经典的当属“生产者和消费者的问题”。生产者和消费者的规则是生产者生产一个产品后,消费者才能消费,并且在消费者还没有消费已经生产的产品的时候,生产者是不能再进行生产的。牛涛写的这个例子演示了这一过程:<br /><br />#include<linux/init.h><br />#include<linux/module.h><br />#include<linux/sem.h><br />#include<linux/sched.h><br />MODULE_LICENSE('Dual BSD/GPL');<br />struct semaphore sem_producer;/*'生产需求证',在产品没有被消费的时候不能再进行生产*/<br />struct semaphore sem_consumer;/*'消费证',在有产品的时候(可以获得该锁)才可以消费*/<br />char product[10];/*'产品'存放地*/<br />int exit_flags;/*生产线开启标志*/<br />int producer(void *product);/*生产者*/<br />int consumer(void *product);/*消费者*/<br />static int procon_init(void)<br />{<br /> printk(KERN_INFO'show producer and consumer\n');<br /> init_MUTEX(&sem_producer);/*购买'生产需求证',并且准许生产*/<br /> init_MUTEX_LOCKED(&sem_consumer);/*购买'消费证',但不可消费*/<br /> exit_flags=0;/*生产线可以开工*/<br /> kernel_thread(producer,product,CLONE_KERNEL);/*启动生产者*/<br /> kernel_thread(consumer,product,CLONE_KERNEL);/*启动消费者*/<br /> return 0;<br />}<br />static void procon_exit(void)<br />{<br /> printk(KERN_INFO'exit producer and consumer\n');<br />}<br />/*<br />* 生产者,负责生产十个产品<br />*/<br />int producer(void *p)<br />{<br /> char *product=(char *)p;<br /> int i;<br /> for(i=0;i<10;i++) { /*总共生产十个产品*/<br /> /* 查看'生产需求证',如果产品已经被消费,<br /> * 则准许生产。否则在此等待直到需要生产<br /> */<br /> down(&sem_producer);<br /> snprintf(product,10,'product-%d',i);/*生产产品*/<br /> printk(KERN_INFO'producer produce %s\n',product);/*生产者提示已经生产*/<br /> up(&sem_consumer);/*为消费者发放'消费证'*/<br /> }<br /> exit_flags=1;/*生产完毕,关闭生产线*/<br /> return 0;<br />}<br />/*<br />* 消费者,如果有产品,则消费产品<br />*/<br />int consumer(void *p)<br />{<br /> char *product=(char *)p;<br /> for(;;) {<br /> if(exit_flags) /*如果生产工厂已经关闭,则停止消费*/<br /> break;<br /> /*获取'消费证',如果有产品,则可以获取,<br /> *进行消费。否则等待直到有产品。<br /> */<br /> down(&sem_consumer);<br /> printk(KERN_INFO'consumer consume %s\n',product);/*消费者提示获得了产品*/<br /> memset(product,'\ 0',10);/*消费产品*/<br /> up(&sem_producer);/*向生产者提出生产需求*/<br /> }<br /> return 0;<br />}<br />module_init(procon_init);<br />module_exit(procon_exit);<br />MODULE_AUTHOR('Niu Tao');<br />MODULE_DESCRIPTION('producer and consumer Module');<br />MODULE_ALIAS('a simplest module');<br /><br />Makefile:<br /><br />obj-m :=procon.o<br />CURRENT_PATH := $(shell pwd)<br />LINUX_KERNEL := $(shell uname -r)<br />LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL)<br />all:<br /> make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules <br />clean:<br /> rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions Module.symvers .Makefile.swp<br /><br />运行结果:<br />[ 5684.818139] show producer and consumer<br />[ 5684.818352] producer produce product-0<br />[ 5684.819746] consumer consume product-0<br />[ 5684.819811] producer produce product-1<br />[ 5684.820061] consumer consume product-1<br />[ 5684.820065] producer produce product-2<br />[ 5684.820267] consumer consume product-2<br />[ 5684.820271] producer produce product-3<br />[ 5684.820498] consumer consume product-3<br />[ 5684.820503] producer produce product-4<br />[ 5684.820822] consumer consume product-4<br />[ 5684.820828] producer produce product-5<br />[ 5684.821062] consumer consume product-5<br />[ 5684.821067] producer produce product-6<br />[ 5684.821274] consumer consume product-6<br />[ 5684.821279] producer produce product-7<br />[ 5684.821475] consumer consume product-7<br />[ 5684.821479] producer produce product-8<br />[ 5684.821681] consumer consume product-8<br />[ 5684.821685] producer produce product-9<br />[ 5684.821897] consumer consume product-9<br />[ 5705.169930] exit producer and consumer<br /> |
|