【问题标题】:find if task 'target' is descendant of task `ancestor` (linux kernel tasks)查找任务“目标”是否是任务“祖先”的后代(Linux 内核任务)
【发布时间】:2017-02-28 06:46:17
【问题描述】:

这是我目前的解决方案:

int is_descendant(task_t* ansc, task_t* targ)
{
    task_t* p_tmp;
    for(p_tmp = targ ; (p_tmp) && (ansc) && (p_tmp->pid) && (p_tmp->pid != ansc->pid) ; p_tmp = p_tmp->p_pptr) ; 
    if((!p_tmp) || (!current) || (!p_tmp->pid)) return -ESRCH;
    return 0;
}

它有效,但我不确定几件事:

  1. 如果不检查p_tmp->pid == 0是否永远迭代,这是否意味着第一个进程的父指针不为NULL?

  2. 是否需要检查p_tmpansc是否为NULL?

  3. 有没有更好的方法来做到这一点? (使用 O(1) 空间计算)

  4. 宏与函数?

    谢谢

【问题讨论】:

  • task_t 类型是什么?现代 Linux 内核中没有这种类型。如果您的意思是 task_struct 对象,那么它有 .parent 字段表示此任务的父级。
  • 我在内核 2.4 上,task_t 定义为 typedef struct task_struct task_t

标签: linux process kernel task


【解决方案1】:

这是否意味着第一个进程的父指针不为NULL?

根据sources初始化任务的父级就是这个任务本身。

是否需要检查p_tmpansc是否为NULL?

父任务(->p_pptr)不能为NULL,所以p_tmp也不能为NULL。

ansc 是函数的参数,在函数体内没有被修改。函数是否应该接受 NULL 由设计决定。

有没有更好的方法来做到这一点? (使用 O(1) 空间计算)

由于任务既不存储指向其所有祖先也不指向其所有后代的指针,因此您不能在恒定时间执行操作 (O(1))。

int is_descendant(task_t* ansc, task_t* targ)
{
    task_t* p_tmp;
    if(ansc->pid == 0) return 0; // init task is ansestor for all tasks.
    for(p_tmp = targ; p_tmp->pid; p_tmp = p_tmp->p_pptr)
        if(p_tmp == ansc) return 0; // Found path to 'ansc'
    // Reach init task without touching 'ansc'.
    return 1;
}

【讨论】:

    【解决方案2】:

    至于4.:您希望通过使用宏而不是函数来获得什么?使用函数而不使用宏几乎总是更好。

    宏的基本问题包括(但不一定限于)以下:

    • 宏容易出错,因为它们使用文本替换。他们可能并不总是按照您的期望行事,而且发现这些错误并非总是那么容易。
    • 宏可能会导致不必要的副作用,例如多次计算表达式。
    • 宏不能返回您的return NOTDESCENDANT 行中的值。 (如果宏在具有匹配返回类型的函数内部使用,它可能会起作用。)
    • 编写(可能还包括读取)跨多行的宏很痛苦。

    这里也讨论了所有这些要点:Macro vs Function in C 您还可以在那里查看所有这些问题的一些示例。

    底线:如有疑问,请始终使用函数或内联函数而不是宏。

    【讨论】:

    • 谢谢,我应用了这种做法并编辑了我原来的问题。事实上,我在内核中看到了很多宏,并认为这是为内核编码时的某种约定。仍然希望得到其他问题的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-17
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 2011-12-03
    • 2022-11-25
    相关资源
    最近更新 更多