linux 模块间通信--使用信号量

我定义了两个信号量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












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值