转自:http://book.2cto.com/201307/27049.html

文件包含:

#include <linux/module.h>

函数定义:

函数在内核源码中的位置:linux-2.6.30/kernel/module.c

函数定义格式:void module_put(struct module *module)

函数功能描述:

该函数的功能是将一个特定模块module的引用计数减1 ,这样当一个模块的引用计数因为不为0而不能从内核中卸载时,可以调用此函数一次或多次,实现对模块计数的清零,从而实现模块卸载。

输入参数说明:

module:指向模块结构体的指针,结构体中包含模块的名称、状态、所属的模块链表等。关
于结构体struct module 的定义,请参见本章中find_module( ) 函数的分析。

返回参数说明:

该函数没有返回值。

实例解析:

编写测试文件:module_put.c

头文件及全局变量声明如下:
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
static int __init module_put_init(void);
static void __exit module_put_exit(void);
模块加载函数:
int __init module_put_init(void)
{
const char *name = "test_module";     //定义待查找的模块名为"test_module"
struct module * fmodule = find_module( name );  //调用查找模块函数
if( fmodule != NULL )
{
/*调用module_put( )函数之前,输出模块test_moudule的引用计数*/
printk("<0>before calling module_put,\n");
printk("<0>refs of %s is: %d\n",name,module_refcount(fmodule));
module_put(fmodule);   // 调用module_put( )函数
/*调用module_put( )函数之前,输出模块test_moudule的引用计数*/
printk("<0>after calling module_put,\n");
printk("<0>refs of %s is: %d\n",name,module_refcount(fmodule));
}
else
{
printk("<0>find %s failed!",name);
}
return 0;
}

模块退出函数:
void __exit module_put_exit(void)
{
printk("<0>module exit ok!\n");
}

模块加载、退出函数调用:
module_init(module_put_init);
module_exit(module_put_exit);

实例运行结果及分析:

首先执行命令lsmod | head -4 ,然后编译模块,执行命令insmod module_put.ko  插入模块,再执行命令dmesg -c ,将出现如图2-17 所示的结果。

结果分析:

在该测试程序中,首先通过“lsmod | head -4 ”命令获取一些模块的信息,这里主要关注模块“test_module ”,该模块是笔者动态插入的模块。在图2-17中上方的白色部分,可以看到模块“test_module ”的引用计数为1 。

然后测试module_put( )函数的功能。首先调用find_module( ) 内核函数查找名为“test_module”的模块,查找模块返回不为空后,再调用module_put( ) 函数实现对模块“test_module ”的引用计数减1 。图2-17中的黑色部分为运行结果,从中可以看到,在调用module_put( )之前,引用计数为1 ,调用module_put( )之后,模块“test_module”的引用计数因减1 而变为了0 。

最后,再通过“lsmod | head -4 ”命令获取模块“test_module ”的信息,从图2-17 中下方白色部分的显示结果可知,模块“test_module”的引用计数确实变为了0 。

实例程序中调用了函数find_module( ) 和函数module_refcount( )。函数find_module( ) 是根据模块名查找模块并返回查找到的模块,函数module_refcount( )则是用来获得模块被引用的次数。关于这两个函数的详细说明见本章中关于它们的分析。

最新文章

  1. MySQL中EXPLAIN命令详解
  2. Symantec Backup Exec 2012 Agent for Linux 卸载
  3. WPF系列 Path表示语法详解(Path之Data属性语法)
  4. Recover data from reference electrode via EEGLab 用EEGLab恢复参考电极数据
  5. 16083001(古墓丽影GPA)
  6. MySQL 入门知识点
  7. 【C-001】printf理解
  8. PPTP --VPN配置
  9. 得到创建人Id
  10. PHP把数字ID转字母ID
  11. mov sreg, r/m16 在16位和32位编程中的区别
  12. js模拟form表单提交数据, js模拟a标签点击跳转,避开使用window.open引起来的浏览器阻止问题
  13. window django-https 证书
  14. mysql报错:Cause: com.mysql.jdbc.PacketTooBigException
  15. python-模块入门二(模块循环导入,区分python文件的两种用途,模块搜索路径,软件开发的目录规范)
  16. mysql日常处理
  17. 基础004_V7-DSP Slice
  18. 20145127《java程序设计》第四周学习总结
  19. leetcode496
  20. shell中set的用法(转)

热门文章

  1. Sql面试题之三(难度:简单| 含答案)
  2. cocos2d-x 键盘和鼠标事件
  3. 用Fluent实现MySQL到ODPS数据集成
  4. 问题 E: 完数与盈数
  5. 并查集——poj1611(入门)
  6. C++-STL:vector用法总结
  7. 简单理解DES加密算法
  8. Dispose的调用顺序
  9. 基于twemproxy和vip实现redis集群的无感知弹性扩容
  10. 文本太长,用省略号显示的css样式