免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2677 | 回复: 10
打印 上一主题 下一主题

[内核模块] 获取某个进程的子进程的问题 [复制链接]

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-12-20 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-10-15 19:47 |只看该作者 |倒序浏览
想在内核模块中获取init_task进程的子进程,代码如下:
  1. #include <linux/module.h>
  2. #include <linux/sched.h>
  3. #include <linux/kernel.h>
  4. #include <linux/list.h>

  5. int init_children_init(void)
  6. {
  7.     struct task_struct *p, *q;

  8.     p = &init_task;
  9.     printk(KERN_DEBUG "1:%s:%d",p->comm, p->pid);
  10.     q = list_entry(&(p->children).next, struct task_struct, children);
  11.     printk(KERN_DEBUG "2:%s:%d\n", q->comm, q->pid);
  12.     return 0;
  13. }
  14. void init_children_exit(void)
  15. {
  16. }

  17. module_init(init_children_init);
  18. module_exit(init_children_exit);
复制代码
为什么编译,加载模块后,dmesg的输出是
1:swapper:0
2:swapper:0

init_task 进程号不应该是1吗,还有p->children.next 应该是他的第一个子进程?为啥结果是这样?

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-12-20 06:20:00
2 [报告]
发表于 2013-10-15 21:34 |只看该作者
做等大神。。。

论坛徽章:
1
天蝎座
日期:2013-10-23 21:11:03
3 [报告]
发表于 2013-10-15 21:51 |只看该作者
本帖最后由 openspace 于 2013-10-15 21:52 编辑

可以加上 p != &init_task 看看输出是怎么样的
或者多打印几个看看是否结果一样

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
4 [报告]
发表于 2013-10-15 21:57 |只看该作者
本帖最后由 kiongf 于 2013-10-15 22:01 编辑

回复 1# goingstudy


    init_task是 swapper process的描述符, 也就是第0号进程的描述符(并不是init process!).

        q = list_entry(&(p->children), struct task_struct, sibling); 改成红色字部分.就可以得到你要的init_task的子进程的信息.

       父进程->chlidren是子进程们用silbing链接成的链表的头节点。

       也可以通过list_for_each_entry(q, &(p->children), sibling){#遍历所有p的节点.#}

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-12-20 06:20:00
5 [报告]
发表于 2013-10-15 22:22 |只看该作者
本帖最后由 goingstudy 于 2013-10-15 22:29 编辑

回复 4# kiongf
(1) init_task 不是init process ,但是我用 宏for_each_process(p) 遍历所有的进程,能够打印出1号进程,for_each_process的实现是
for (p=&init_task;(p=next_task(p)) != init_task; )


(2) q = list_entry(&(p->children), struct task_struct, sibling), sibling不是父进程的兄弟吗?
那要是遍历某个进程的兄弟进程呢,还是不太明白,

   

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
6 [报告]
发表于 2013-10-15 22:40 |只看该作者
回复 5# goingstudy


父进程->children用于表示一个链表 的头节点:这个链表的非头节点的节点是该进程的子进程.
  那么也就是说这个链表中的非头节点的节点就都是兄弟了. 那么兄弟进程就用sibling来链接。

  换句话说, 假设init_task(process 0) 有父进程以及兄弟进程.  你如果要遍历process 0的兄弟进程,那么就得通过  list_for_each_entry( &(init_task->parent->children), struct task_struct, sibling)来访问。

(他们是兄弟进程, 同时也是一个进程的子进程)

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-12-20 06:20:00
7 [报告]
发表于 2013-10-15 22:48 |只看该作者
回复 6# kiongf

thank you,有点明白了
   

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-12-20 06:20:00
8 [报告]
发表于 2013-10-15 23:21 |只看该作者
回复 4# kiongf
应该是
q= list_entry((p->children).next,struct task_struct, sibling);

p->children是p的子进程的队列头,p->children.next才是第一个子进程。

   

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
9 [报告]
发表于 2013-10-15 23:55 |只看该作者
回复 8# goingstudy


    是的.  

这是我写的遍历所有进程的代码():

13 void read_child(struct task_struct* p)
14 {
15         struct task_struct *q = NULL;
16         if(!list_empty( &(p->children))){       /*p有子进程*/
17                 list_for_each_entry(q, &(p->children), sibling ){
18         
19                         printk("<7> pid:%d, comm:%s\n",q->pid, q->comm);
20                         read_child(q);
21                 }
22         }
23 }
24
25 static int __init init_mm_init(void)
26 {
27         struct task_struct *p = &init_task;
28         struct task_struct *q = NULL;
29         printk("<7> pid:%d, comm:%s\n",p->pid, p->comm);
30         
31         read_child(p);
              return 0 ;
      }
     

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
10 [报告]
发表于 2013-10-15 23:59 |只看该作者
回复 8# goingstudy


    抱歉, 前面写错了. 应该是:
  
        list_entry(p->children.next, struct task_struct, sibling);
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP