专栏首页嵌入式Linux系统开发手把手教你获取Linux所有进程信息

手把手教你获取Linux所有进程信息

很多时候,我们要监控系统状态,即监控系统cpu负载、进程状态等情况,如果我们在 Linux 应用层,我们有很多方式,命令行中常用 top、ps 命令,代码中,我们可以使用 popen 函数去执行一个 top 命令,获取返回值。或者我们直接读写 /proc下面的文件,都可以达到目的。

但如果要你在内核(驱动)中去获取这些信息,你无法执行 top 命令。即便可以使用 flip_open 函数和加 vfs_read 内核函数去读写 /proc 节点文件,但 Linux 本身不建议这样做,这会破坏节点(驱动)之间的独立性,如果产生依赖关系,很可能产生各种各样的问题:如果你在一个节点驱动中读写另外一个节点的内容,而另外一个挂载出了问题,系统就会不稳定。

所以我们一般直接从 Linux 内核本身获取信息,去分析 Linux 内核源码,从他本身的数据结构(结构体、变量、链表)中获取信息。

今天教大家如何在驱动中直接获取 linux 系统中所有进程信息。进程有很多信息,在 /proc/[pid] 目录中中只放了很少一部分,我们访问内核数据结构可以获取全部所有信息。

我们知道Linux系统管理进程是使用PCB(process control block),进程控制块,内核使用一个结构体描述它,这个结构体现在有600多行,叫 task_struct 结构体,这个结构体在 linux 内核源码 linux/include/linux/sched.h 中。

task.c

# include <linux/kernel.h>
# include <linux/module.h>
# include <uapi/linux/sched.h>
# include <linux/init_task.h>
# include <linux/init.h>
# include <linux/fdtable.h>
# include <linux/fs_struct.h>
# include <linux/mm_types.h>
//内核模块初始化函数
static int __init traverse_pcb(void)
{
 struct task_struct *task, *p;//定义指向task_struct类型的指针
 struct list_head *pos;//定义双向链表指针
 int count=0;//定义统计系统进程个数的变量
 printk("Printf process'message begin:\n");//提示模块开始运行
 task = &init_task;//指向0号进程的PCB
 
 list_for_each(pos,&task->tasks)//使用list_for_each宏来遍历进程链表
 {
  p = list_entry(pos,struct task_struct,tasks);//指向当前进程的task_struct结构
  count++;//统计系统进程个数
  printk("\n\n");//方便查看后续打印信息
  /*
  打印task_struct中的字段.comm:name.pid:进程的pid号;state:进程的状态;
  prio:动态优先级;static_prio:静态优先级; parent'pid:父进程的pid号;
  count:文件系统信息,文件被使用的次数; umask:进程权限位的默认设置;
  使用atomic_read原子操作是为了(p->files)->count字段计数不被打断
  */
  printk("comm:%s; pid:%d; state:%lx; prio:%d; static_prio:%d; parent'pid:%d; count:%d; umask:%d;", \
   p->comm,p->pid,p->state,p->prio,p->static_prio,(p->parent)->pid,        \
   atomic_read((&(p->files)->count)),(p->fs)->umask);
  //打印进程地址空间的信息
  if((p->mm)!=NULL)
   printk("total_vm:%ld;",(p->mm)->total_vm);//total_vm:线性区总的页数
 }
 printk("进程的个数:%d\n",count);//打印进程个数
 return 0;
}
 
//内核模块退出函数
static void __exit end_pcb(void)
{
 printk("traverse pcb is end.");
}
module_init(traverse_pcb);//入口
module_exit(end_pcb);//出口
MODULE_LICENSE("GPL");//许可证

Makefile

KERNELDIR := /home/book/linux/tool/kernel/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek

CURRENT_PATH := $(shell pwd)

obj-m := task.o

build: kernel_modules

kernel_modules:
 $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules

clean:
 $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

编译

我们会编译出一个task.ko内核模块,把它拷贝到板子中,进行挂载。

挂载上以后就会触发 _init 函数,就会打印。当然我们也可以把这段代码放在 xxx_read 函数中,在 _init 函数中创建节点,访问一次节点就打印一次,都可以。

博主这个系统进程很少,只有 70-80 个,是 buildroot 自己编译的文件系统,没有什么功能。

我们通过定义的p结构体指针,可以访问系统中所有进程的 io、运行时间、内存信息、进程被调用次数,任何和进程有关的信息都存在于 task_struct 中。

Linux 内核采用 task_struct 来描述一个进程。当系统起来以后,随着 init(pid=1)进程 fork 出其他进程,会有一个双向链表,将所有的由 init 创建的进程串起来,我们通过遍历这个双向链表,进而获取所有进程的 task_struct 结构体,把信息取出来。在驱动中这样做,远比访问 /proc 文件方便多了。

note:编译之前记得准备好你的 Linux 内核源码,因为编译需要引用头文件,所以我们在 Makefile 中写明 Linux 内核源码目录(源码必须是编译过的源码,编译 Linux 大概需要半个多小时)。另外需要注意,你编译驱动所引用的内核和你板子中真正运行的 Linux 内核要需要是同一个版本,否则挂载不上去。

·················· END ··················

本文分享自微信公众号 - 嵌入式Linux系统开发(Jason_Linux_),作者:Jasonangel

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-08-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 手把手教你用Python网络爬虫获取头条所有好友信息

    大家好,我是黄伟。今日头条我发觉做的挺不错,啥都不好爬,出于好奇心的驱使,小编想获取到自己所有的头条好友,

    Python进阶者
  • 手把手|50行Python代码教你爬取猫眼电影TOP100榜所有信息

    对于Python初学者来说,爬虫技能是应该是最好入门,也是最能够有让自己有成就感的,今天,恋习Python的手把手系列,手把手教你入门Python爬虫,爬取猫眼...

    Python数据科学
  • 手把手教你使用Python网络爬虫获取菜谱信息

    今天教大家去爬取下厨房的菜谱 ,保存在world文档,方便日后制作自己的小菜谱。

    Python进阶者
  • 手把手教你使用Python网络爬虫获取招聘信息

    现在在疫情阶段,想找一份不错的工作变得更为困难,很多人会选择去网上看招聘信息。可是招聘信息有一些是错综复杂的。而且不能把全部的信息全部罗列出来,以外卖的58招...

    用户1564362
  • 手把手教你爬取研招网调剂信息

    这篇文章是去年我在博客上写的一篇基础爬虫,利用了简单的Python爬虫来定时收集目标专业的调剂信息,后面也确实帮助我成功上岸。

    老肥码码码
  • 手把手教你利用Python网络爬虫获取APP推广信息

    CPA之家app推广平台是国内很大的推广平台。该网址的数据信息高达数万条,爬取该网址的信息进行数据的分析。

    Python进阶者
  • 手把手教你利用Python网络爬虫获取旅游景点信息

    当我们出去旅游时,会看这个地方有哪些旅游景点,景点价格、开放时间、用户的评论等。

    用户1564362
  • 手把手教你利用Python网络爬虫获取旅游景点信息

    当我们出去旅游时,会看这个地方有哪些旅游景点,景点价格、开放时间、用户的评论等。

    Python进阶者
  • 手把手教你用python爬取猫眼TOP100电影信息

    在生活中,我们如果想要对网站上的数据进行使用的话,一般我们都会使用复制粘贴的方法进行复制过来,但如果数据量很多的话,你就会像个机械人一样做着重复的事,而使用Py...

    Python与Excel之交
  • 手把手教你利用Python网络爬虫获取链家网的房产信息

    随着人们生活方式的的提高,房子成为了我们必不可少的一部分。而网上的信息太过于复杂,为了了解最近房价的变化趋势。小编以链家这个网站为例,抓取房价的信息。

    用户7466307
  • 手把手教你利用Python网络爬虫获取链家网的房产信息

    随着人们生活方式的的提高,房子成为了我们必不可少的一部分。而网上的信息太过于复杂,为了了解最近房价的变化趋势。小编以链家这个网站为例,抓取房价的信息。

    Python进阶者
  • 手把手教你利用Python网络爬虫获取链家网的房产信息

    随着人们生活方式的的提高,房子成为了我们必不可少的一部分。而网上的信息太过于复杂,为了了解最近房价的变化趋势。小编以链家这个网站为例,抓取房价的信息。

    朱小五
  • 手把手教你用Python爬取快递100查询你的物流信息

    快递鸟集合了多家快递公司查询接口,输入相应快递公司编码和快递单号就可以获取到对应的物流信息很方便快捷。

    刘早起
  • 图片爬虫,手把手教你Python多线程下载获取图片

    图片站lemanoosh数据为异步加载的形式,往下拉会展示更多数据,也就是下一页数据,通过谷歌浏览器可以很清晰的看到数据接口地址,以及数据展现形式,与其他网站返...

    二爷
  • 隐私泄漏严重,只通过手机号可能获取你的所有信息

    上面这句话绝不是危言耸听,只要你是一个现代人,需要通过手机来注册一系列的社交软件和网站,那你的身份信息泄露的几率就会非常之高。

    华章科技
  • 手把手教你企业微信SCRM源码下载和私有化部署教程

    MoChat 对系统环境有一些要求,仅可运行于 Linux 和 Mac 环境下,但由于 Docker 虚拟化技术的发展,在 Windows 下也可以通过 Doc...

    MoChat摩言
  • 搜狗微信下线了怎么获取公众号文章?最新方式手把手教你

    最近发现搜狗微信在2019.10.29号的时候悄然下线了一个功能,也就是不能在搜狗搜索中指定公众号的名称,如下图

    云爬虫技术研究笔记
  • 手把手教你完成微信小程序用户信息绑定(微信报修小程序源码讲解八)

    1、打开微信开发工具,找到 app.json 文件,在 app.json 下添加一个页面:pages/binding/index

    热心的程序员
  • Linux搭建甜糖星愿服务教程,挂机赚钱

    群晖NAS搭建甜糖星愿服务教程:https://www.awsl9527.cn/archives/539.html

    zeruns

扫码关注云+社区

领取腾讯云代金券