Linux内核API完全参考手册(第2版)
上QQ阅读APP看书,第一时间看更新

3.7 函数:mmput( )

文件包含:

        #include <linux/sched.h>

函数定义:

在内核源码中的位置:linux-3.19.3/kernel/fork.c

函数定义格式:void mmput(struct mm_struct *)

函数功能描述:

此函数用于减少任务对应的内存空间的用户的数量,并在当用户数量减少到0时释放任务所占用的内存空间。

输入参数说明:

此函数的输入参数是一个struct mm_struct类型的结构体变量,对应任务的内存空间,其定义及详细解释请读者自行参考本章函数get_task_mm( )分析文档的返回参数说明部分。

返回参数说明:

此函数的返回值是void类型的变量,即不返回任何结果。

实例解析:

编写测试文件:mmput.c

头文件引用:

        #include <linux/module.h>
        #include <linux/sched.h>
        #include <linux/pid.h>
        #include <linux/mm_types.h>
        MODULE_LICENSE("GPL");

模块加载函数定义:

        static int __init mmput_init(void)
        {
            printk("into mmput_init.\n");
            struct pid * kpid=find_get_pid(current->pid);         //获取当前进程的描述符信息
            struct task_struct * task=pid_task(kpid, PIDTYPE_PID); //获取新进程的任务描述符信息
            struct mm_struct * mm_task=get_task_mm(task);         //获取进程对应任务的内存信息

            /*显示字段mm_users和字段mm_count的值*/
            printk("the mm_users of the mm_struct is:%d\n", mm_task->mm_users);
            printk("the mm_count of the mm_struct is:%d\n", mm_task->mm_count);

            /*显示与此mm_struct相关进程的父进程的TGID和PID*/
            printk("the tgid of the mm_strcut is:%d\n", mm_task->owner->tgid);
            printk("the pid of the mm_struct is:%d\n", mm_task->owner->pid);
            mmput(mm_task);            //调用函数mmput( )释放进程的内存空间
            printk("the new value of the mm_struct after the function mmput:\n");

            /*显示函数mmput( )调用之后的进程对应内存空间部分字段的值*/
            printk("the mm_users of the mm_struct is:%d\n", mm_task->mm_users);
            printk("the mm_count of the mm_struct is:%d\n", mm_task->mm_count);
            printk("the tgid of the mm_strcut is:%d\n", mm_task->owner->tgid);
            printk("the pid of the mm_struct is:%d\n", mm_task->owner->pid);
            printk("the current PID is:%d\n", current->pid);       //显示当前进程的PID值
            printk("out mmput_init.\n");
            return 0;
        }

模块退出函数定义:

        static void __exit mmput_exit(void)
        {
            printk("Goodbye mmput\n");
        }

模块加载、退出函数调用:

        module_init(mmput_init);
        module_exit(mmput_exit);

实例运行结果及分析:

首先编译模块,执行命令insmod mmput.ko插入模块,然后执行命令dmesg -c,会出现如图3-7所示的结果。

图3-7 插入mmput模块系统输出信息

结果分析:

由图3-7可以看出函数mmput( )运行之后字段mm_users的值减小了,即任务的用户数量少了一个。

在函数mmput( )执行之初,调用了函数might_sleep( ),这样就给进程之间的切换提供了机会。