热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

进程管理–Linux内核APIget_task_mm

get_task_mm函数功能描述:此函数根据提供的任务描述符信息,获取其对应的内存信息,此内存信息保存在mm_struct结构体类型的变量中。

get_task_mm函数功能描述:此函数根据提供的任务描述符信息,获取其对应的内存信息,此内存信息保存在mm_struct结构体类型的变量中。

get_task_mm文件包含

#include

get_task_mm函数定义

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

函数定义格式:

struct mm_struct *get_task_mm(struct task_struct *task)

get_task_mm输入参数说明

此函数的返回结果是struct task_struct结构体类型的变量,保存符合条件的任务描述符信息,其定义参见内核源码文件linux-3.19.3/include/linux/sched.h,其内核注释比较详细,请读者自行分析。

get_task_mm返回参数说明

此函数的返回结果是任务描述符对应的内存信息,即某任务对应的内存信息,是一个struct mm_struct类型的变量,其定义在文件linux-3.19.3/include/linux/mm_types.h中,如下所示:

struct mm_struct {
struct vm_area_struct * mmap; //指向线性区对象的链表头
struct rb_root mm_rb;
u32 vmacache_seqnum; //每一个进程的vmacache大小
#ifdef CONFIG_MMU
/* 在进程地址空间中搜索有效线性地址区间的方法 */
unsigned long (*get_unmapped_area) (struct file *filp, unsigned long addr,unsigned long len, unsigned long pgoff, unsigned long flags);
#endif
/*释放线性地址区间时调用的方法 */
unsigned long mmap_base; //标识第一个分配的匿名线性区或文件内存映射的线性地址
unsigned long mmap_legacy_base; //mmap区域自下而上的分配区
unsigned long task_size; //在vm空间任务大小
unsigned long highest_vm_end; //最大vma的结束地址
pgd_t * pgd; //指向页全局目录
atomic_t mm_users; //次使用计数器
atomic_t mm_count; //主使用计数器
atomic_long_t nr_ptes; //页表所在的页地址
int map_count; //线性区vma的个数
spinlock_t page_table_lock; //线性区的自旋锁和页表的自旋锁
struct rw_semaphore mmap_sem; //线性区的读/写信号量
struct list_head mmlist; //指向内存描述符链表中的相邻元素
unsigned long hiwater_rss;
unsigned long hiwater_vm;
/*total_vm指进程地址空间的大小(页数), locked_vm指“锁住”而不能换出的页的个数,
shared_vm指共享文件内存映射中的页数,exec_vm指可执行内存映射中的页数*/
unsigned long total_vm, locked_vm, pinned_vm, shared_vm, exec_vm;
/*stack_vm指用户堆栈中的页数*/
unsigned long stack_vm, def_flags;
/*start_code指可执行代码的起始地址,end_code指可执行代码的最后地址,start_data指已
初始化数据的起始地址,end_data指已初始化数据的最后地址*/
unsigned long start_code, end_code, start_data, end_data;
/*start_ brk指堆的起始地址,brk指堆的当前最后地址,start_ stack指用户态堆栈的起始地址*/
unsigned long start_brk, brk, start_stack;
/*arg_start指命令行参数起始地址,arg_end指命令行参数的最后地址,env_start指环境变
量的起始地址,env_end指环境变量的最后地址*/
unsigned long arg_start, arg_end, env_start, env_end;
unsigned long saved_auxv[AT_VECTOR_SIZE]; //开始执行ELF程序时使用
struct mm_rss_stat rss_stat;
struct linux_binfmt *binfmt;
cpumask_var_t cpu_vm_mask_var;
mm_context_t context; //特定于体系结构的MM上下文
unsigned long flags; //必须使用原子操作访问
struct core_state *core_state; //存储器内容更新支持
#ifdef CONFIG_AIO
spinlock_t ioctx_lock;
struct kioctx_table __rcu *ioctx_table;
#endif
#ifdef CONFIG_MEMCG
struct task_struct __rcu *owner;
#endif
/* 存储符号链接/proc//exe指向的文件*/
struct file *exe_file;
#ifdef CONFIG_MMU_NOTIFIER
struct mmu_notifier_mm *mmu_notifier_mm;
#endif
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && ! USE_SPLIT_PMD_PTLOCKS
pgtable_t pmd_huge_pte; //被page_table_lock锁保护
#endif
#ifdef CONFIG_CPUMASK_OFFSTACK
struct cpumask cpumask_allocation;
#endif
#ifdef CONFIG_NUMA_BALANCING
/* numa_next_scan是下一次扫描标记,它被PTEs中的pte_numa所标记 */
unsigned long numa_next_scan;
/* 扫描和设置pte_numa的重启点*/
unsigned long numa_scan_offset;
/* numa_scan_seq阻止两个线程设置pte_numa */
int numa_scan_seq;
#endif
#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION)
/*
* 一个带有批量TLB刷新操作正在运行的情况。
* 当移动PROT_NONE或PROT_NUMA映射页时,任意的能够移动存储处理的事项都需要刷新
*/
bool tlb_flush_pending;
#endif
struct uprobes_state uprobes_state;
#ifdef CONFIG_X86_INTEL_MPX
void __user *bd_addr; //地址范围目录
#endif
};

get_task_mm实例解析

编写测试文件:get_task_mm.c

头文件引用:

#include
#include
#include
#include
MODULE_LICENSE("GPL");

模块加载函数定义:

static int __init get_task_mm_init(void)
{
printk("into get_task_mm_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_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_task相关进程的父进程的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);
printk("the current PID is:%d\n", current->pid); //显示当前进程的PID号
printk("out get_task_mm_init.\n");
return 0;
}

模块退出函数定义:

static void __exit get_task_mm_exit(void)
{
printk("Goodbye get_task_mm\n");
}

模块载、退出函数调用:

module_init(get_task_mm_init);
module_exit(get_task_mm_exit);

实例运行结果及分析:

首先编译模块,执行命令insmod get_task_mm.ko插入模块,然后执行命令dmesg -c查看内核输出信息,会出现如图所示的结果。

Linux内核API get_task_mm

结果分析:

由上图可以看出函数get_task_mm( )能够获得当前进程的信息,在当前进程的内存信息中其父进程的进程号和组进程号都是13384,与显示的当前进程号13384相同,说明函数get_task_mm( )能够成功获取相应进程的内存信息,其中字段mm_users的值是2,代表当前任务的内存空间的用户数量,字段mm_count的值为1,代表此任务的内存空间被引用的次数。


推荐阅读
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
author-avatar
ngdongran_638070
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有