如何获取进程task_struct的最旧非兄弟子进程?
实现思路
你的思路是正确的,Linux内核struct task_struct的子进程链表逻辑如下:
- 每个进程的
children字段是双向链表头,其所有直接子进程都通过自身的sibling节点挂载在这个链表上 - 新创建的子进程默认插入到
children链表的头部,因此链表的尾节点就是最早创建的最旧直接子进程,也就是你要找的最旧非兄弟子进程
示例实现代码
访问进程链表需要持有tasklist_lock锁避免竞态,参考代码如下:
#include <linux/sched.h> #include <linux/list.h> #include <linux/spinlock.h> struct task_struct *get_oldest_child(struct task_struct *parent) { struct task_struct *oldest = NULL; struct task_struct *pos; read_lock(&tasklist_lock); if (list_empty(&parent->children)) goto out_unlock; // 方式1:反向遍历子进程链表,第一个节点就是最旧子进程 list_for_each_entry_reverse(pos, &parent->children, sibling) { oldest = pos; get_task_struct(oldest); break; } /* 方式2:正向遍历到链表尾部,和方式1等价,符合你最初的思路 list_for_each_entry(pos, &parent->children, sibling) { oldest = pos; } get_task_struct(oldest); */ out_unlock: read_unlock(&tasklist_lock); return oldest; }
注意事项
- 调用上述函数拿到返回的
oldest指针使用完毕后,必须调用put_task_struct(oldest)释放引用,避免内存泄漏 tasklist_lock是自旋锁,持有锁期间不能执行可能睡眠的操作
内容的提问来源于stack exchange,提问作者Tan Nguyen
相关产品推荐
相关产品推荐

