我定义了两个信号量sem1和sem2,分别与两个线程进行绑定,从而控制两个线程相互通信。 简单介绍一下我的这个两个内核模块之间使用信号量进行通信的例子。我定义了两个模块,两个模块对一个数组num分别进行读和写。proc1.c中定义了一个写数据的线程,并与信号量sem1绑定。proc2.c中定义了一个读数据的线程,与信号量sem2绑定。当proc1.ko写完一个数据之后,proc2.ko将其读出来。通过EXPORT_SYMBOL来实现存储区的共享。 proc1.c #include <linux/init.h> #include <linux/module.h> #include <linux/sched.h> #include <linux/semaphore.h> #include <linux/kernel.h> MODULE_LICENSE("GPL"); int num[5]={ 0 }; struct semaphore sem1; struct semaphore sem2; EXPORT_SYMBOL(num); //用EXPORT_SYMBOL来声明全局变量 EXPORT_SYMBOL(sem1); EXPORT_SYMBOL(sem2); int thread_write_first(void *); int thread_write_first(void *p) //写线程 { int i; int *num=(int *)p; for(i=0;i<5;i++) { //写数据并释放相应信号量 down(&sem1); num[i]=i*2; printk(KERN_INFO"---write:num[%d]=%d\n",i,num[i]); up(&sem2); } return 0; } static int __init proc1_init(void) { printk(KERN_ALERT"proc1 enter\n"); sema_init(&sem1,1); sema_init(&sem2,0); kernel_thread(thread_write_first,num,CLONE_KERNEL); return 0; } static void __exit proc1_exit(void) { printk(KERN_ALERT"proc1 exit\n"); } module_init(proc1_init); module_exit(proc1_exit); proc1.c对应的Makefile obj-m:=proc1.o CURRENT_PATH:=$(shell pwd) VERSION_NUM:=$(shell uname -r) LINUX_PATH:=/usr/src/linux-headers-$(VERSION_NUM) all: make -C $(LINUX_PATH) M=$(CURRENT_PATH) modules clean: make -C $(LINUX_PATH) M=$(CURRENT_PATH) clean proc1模块make之后可得到一个Module.sysvers文件,其中包含了我们所定义的全局变量,在模块proc2的Makefile中,我们要将该文件添加进去 0x9af39f68 sem1 /home/qinm/Desktop/ipc/export/proc1/proc1 EXPORT_SYMBOL 0x3bf74e21 num /home/qinm/Desktop/ipc/export/proc1/proc1 EXPORT_SYMBOL 0xe9a8c512 sem2 /home/qinm/Desktop/ipc/export/proc1/proc1 EXPORT_SYMBOL 进入文件夹后,分别执行sudo make和sudo insmod proc1.ko proc2.c #include <linux/init.h> #include <linux/sched.h> #include <linux/semaphore.h> #include <linux/kernel.h> MODULE_LICENSE("GPL"); extern int num[5]; extern struct semaphore sem1; extern struct semaphore sem2; int thread_read_second(void *p); int thread_read_second(void *p) //读线程 { int i; int *num=(int *)p; for(i=0;i<5;i++) { //读数据并释放相应信号量 down(&sem2); printk(KERN_INFO"read:%d\n",num[i]); up(&sem1); } return 0; } static int __init proc2_init(void) { printk(KERN_ALERT"proc2 enter\n"); kernel_thread(thread_read_second,num,CLONE_KERNEL); return 0; } static void __exit proc2_exit(void) { printk(KERN_ALERT"proc2 exit\n\n\n"); } module_init(proc2_init); module_exit(proc2_exit); proc2模块对应的Makefile obj-m:=proc2.o KBUILD_EXTRA_SYMBOLS=/home/qinm/Desktop/ipc/proc1/Module.symvers //增加这一句,否则会出现未定义错误 CURRENT_PATH:=$(shell pwd) VERSION_NUM:=$(shell uname -r) LINUX_PATH:=/usr/src/linux-headers-$(VERSION_NUM) all: make -C $(LINUX_PATH) M=$(CURRENT_PATH) modules clean: make -C $(LINUX_PATH) M=$(CURRENT_PATH) clean 进入文件夹之后分别执行sudo make 和sudo insmod proc2.ko
linux 模块间通信--使用信号量
最新推荐文章于 2021-05-03 15:40:49 发布