当前位置: 首页 > news >正文

linux 内核: 遍历当前所有进程

一:概述

        在 Linux 内核中,每个进程都由一个 task_struct 结构体表示,它是内核中用于描述进程和线程的核心数据结构。内核通过一个全局链表维护所有的进程信息,for_each_process(p) 宏可用于遍历该链表中的所有进程。由于进程链表是全局共享资源,若不加锁直接访问,可能导致读取到无效数据甚至系统崩溃。传统的 read_lock(&tasklist_lock) 机制在现代内核中已被废弃或不对模块导出。因此,本示例使用 RCU(Read-Copy-Update)机制对进程链表进行并发安全的读取操作。        

二: 实现

        1. 加锁(RCU)   

rcu_read_lock()

        遍历进程链表是读访问共享数据,需要加锁。这里使用的是RCU读锁(Read-Copy-Update),是Linux内核中一种轻量、高效的读保护机制,因为老 tasklist_lock不对模块导出(不能直接用) ,所以推荐用rcu_read_lock() / rcu_read_unlock() 保护task_struct 的代码。

        2. 遍历进程

for_each_process(p) 

        for_each_process(p) 是一个宏,用于遍历系统中所有进程的 task_struct 链表,p 是当前进程的指针。

        3. 打印每个进程信息

get_task_struct(p);   // 增加引用计数,防止进程被销毁
n = snprintf_lkp(tmp, 128, "%-16s|%8d|%8d|%7u|%7u\n",p->comm, p->tgid, p->pid,__kuid_val(p->cred->uid), __kuid_val(p->cred->euid));
put_task_struct(p);   // 释放引用
pr_info("%s", tmp);

          get_task_struct()put_task_struct() 是对 task_struct 增减引用计数的 API,保证遍历期间该进程结构不会被释放。

     4. 解锁

rcu_read_unlock();

三:完整例子 

#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>  // for_each_process
#include <linux/cred.h>          // __kuid_val
#include <linux/rcupdate.h>      // rcu_read_lock/unlockMODULE_AUTHOR("MyName");
MODULE_DESCRIPTION("List all processes in task list");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");static int show_all_processes(void)
{struct task_struct *p;char buf[128];int total = 0;pr_info("     Name       |  TGID  |  PID   |  RUID  |  EUID\n");rcu_read_lock();for_each_process(p) {snprintf(buf, sizeof(buf), "%-16s|%8d|%7d|%7u|%7u\n",p->comm,p->tgid,p->pid,__kuid_val(p->cred->uid),__kuid_val(p->cred->euid));pr_info("%s", buf);total++;}rcu_read_unlock();return total;
}static int __init prcs_showall_init(void)
{int count = show_all_processes();pr_info("Total processes: %d\n", count);return 0;
}static void __exit prcs_showall_exit(void)
{pr_info("Module removed\n");
}module_init(prcs_showall_init);
module_exit(prcs_showall_exit);

  


文章转载自:
http://chauffeur.tmizpp.cn
http://begone.tmizpp.cn
http://anfractuosity.tmizpp.cn
http://callipers.tmizpp.cn
http://beastly.tmizpp.cn
http://carthago.tmizpp.cn
http://abstriction.tmizpp.cn
http://catananche.tmizpp.cn
http://charpit.tmizpp.cn
http://chambray.tmizpp.cn
http://breast.tmizpp.cn
http://benempted.tmizpp.cn
http://cardindex.tmizpp.cn
http://burnouse.tmizpp.cn
http://cerulean.tmizpp.cn
http://brimming.tmizpp.cn
http://chloramine.tmizpp.cn
http://aurific.tmizpp.cn
http://belting.tmizpp.cn
http://brassin.tmizpp.cn
http://accidentally.tmizpp.cn
http://ceorl.tmizpp.cn
http://bytom.tmizpp.cn
http://blamed.tmizpp.cn
http://boulangism.tmizpp.cn
http://asbestus.tmizpp.cn
http://astronomical.tmizpp.cn
http://ashamed.tmizpp.cn
http://anteprohibition.tmizpp.cn
http://castalian.tmizpp.cn
http://www.dtcms.com/a/280237.html

相关文章:

  • 【科研绘图系列】R语言绘制中国地图和散点图以及柱状图
  • Oracle学习专栏(六):高可用架构
  • 代码随想录八股文训练营总结
  • Ai推理助手易语言开源版
  • 【解决】联想电脑亮度调节
  • SAP学习笔记 - 开发45 - RAP开发 Managed App New Service Definition,Metadata Extension
  • c++图形题练习程序
  • 【工程篇】07:如何打包conda环境并拷贝到另一台服务器上
  • HAProxy双机热备,轻松实现负载均衡
  • 【开源】一款基于 .NET 和 Vue3 开源(Apache)的MES管理系统,您的新一代工厂管理助手!
  • 昆仑通态触摸屏脚本编程通讯设置和调试
  • 【亲测有效】ubuntu20.04服务器新建用户+vnc配置教程
  • Racknerd服务器Ubuntu
  • Ant Design预览多张图
  • AR眼镜颠覆医疗:精准手术零误差
  • HTML--教程
  • K-12教育创业新蓝图:告别“刷题”,拥抱“千人千面”个性化学习
  • 物联网设备管理工具实战:用AR运维镜击穿6.8天修复魔咒
  • Bootstrap-HTML(七)Bootstrap在线图标的引用方法
  • 【zynq7020】PS的“Hello World”
  • RHCE认证-Linux 运维知识整合:从基础到进阶的学习路径
  • ESP32S3+VSCode+PlatformIO+Arduino+Freertos开发入门指南:基于Arduino框架的应用开发全流程
  • 多维视角下的可组合性:PTBs 与 EIP-7702 的对比与解析
  • 简单明了的对比PyTorch与TensorFlow
  • 操作系统笔记:进程调度(Process Scheduling)
  • 硬件与软件的桥梁:冯诺依曼体系、操作系统和初始进程的深度解析
  • 排序算法实战(上)
  • 串口通信性能优化
  • 人形机器人:技术落地、场景适配与产业演进
  • 卫星通信链路预算之六:输出回退