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/unlock

MODULE_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);

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑不溜秋的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值