Linux 下 进程 or 线程的遍历
内核 API 进程线程 遍历那点事
- 资料来源:
<>
更新
1
2023.12.20 初始
导语
最近遇到个 bug 挺恼人的, 一些情况下就是没有特定 task 的信息… 但实际上是已经获取到了…
归根结底实际上是原来代码中遍历 task_struct 选错了循环结构… 故总结一下:
涉及到遍历 task_struct 的宏基本都在 include/linux/sched/signal.h
和 include/linux/pid.h
下定义
- 不同 linux 版本可能有变化, 这里是 5.17.15 ;
- 例子来自 gpt
基本分为两种类型: do 循环和 for 循环
- do 循环下的 while 宏,一般不建议单独使用,非常容易漏掉个别循环条件.
- 我遇到的 bug 就是 原代码中单独用了 while 没有配合 do, 漏掉了 第一次循环的 task;
- 需要注意同步和锁, 一般需要 rcu 锁;
- 个别是 两层循环, break 不管用,要 goto 才能跳出;
正文
do_each_pid_task(pid, Type, task) { … } while_each_pid_task(pid, Type, task);
遍历 pid 下的 type 类型 的 所有 线程和进程
1 |
|
do_each_pid_thread(pid, Type, task) { … } while_each_pid_thread(pid, Type, task);
类似于 do_each_pid_task
,但专门用于遍历具有特定 PID 的线程。
do_each_thread(g, t) { … } while_each_thread(g, t);
用途: 遍历全部进程的全部线程; 双循环, break 不管用,需要使用 goto;
示例:
1 |
|
for_each_process(p) { … }
遍历系统中的每个进程, 不包括线程
示例:
1 |
|
for_each_process_thread(p, t) { … }
遍历系统中每个进程的所有线程, 双重循环 break 不行,要用 goto
示例
1 |
|
for_each_thread(p, t) { … }
遍历给定进程的所有线程
示例:
1 |
|
结束语
linux kernel 的琐碎让人心力交瘁 😒😒😒😒