2015-05-05 73 views
1

我有一個關於task_struct列表的問題。內核task_struct和同級指針

/* 
* pointers to (original) parent process, youngest child, younger sibling, 
* older sibling, respectively. (p->father can be replaced with 
* p->p_pptr->pid) 
*/ 
task_t *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr; 

我正在使用這些指針來運行進程的子進程。 我不明白(並且很難從內核代碼中理解),如果最小的子列表結尾爲null或是循環的?

我可以穿過所有p_cptr,直到我達到NULL,或者我應該再次回到頭部嗎?

謝謝。

+0

內核鏈接列表是[圓形雙向鏈表](http://en.wikipedia.org/wiki/Doubly_linked_list#Circular_doubly-linked_lists)。所以最後一個元素(尾部)指向第一個元素(頭部)。看看[for_each_process()](http://lxr.free-electrons.com/source/include/linux/sched.h#L2529)宏。 –

+0

無論你使用的是什麼列表。所有列表在內核中都是循環的。它是通過列表函數實現來實現的:他們都在試圖在每次操作後使列表循環。你需要爲你的任務使用的是'list_for_each()'和'list_entry()'函數。詳情請參閱[這個問題](http://stackoverflow.com/questions/8207160/kernel-how-to-iterate-the-children-of-the-current-process)。 –

+0

我不是通過'list_head'指針迭代列表,而是直接通過'task_t'指針進行迭代。 沒有'prev','next'我正在經歷,所以它不是完全一樣的情況。 我正在訪問每個進程的'p_cptr'和'p_osptr',我只是不明白對沒有孩子/老兄弟的進程期望什麼。 –

回答

1

嘗試下面的代碼。我沒有在內核2.4(僅在4.0)上測試過它,但我認爲它應該適用於2.4,而且幾乎沒有修改。例如,我使用kthreadd過程作爲父項,因爲它有很多子項。

#include <linux/module.h> 
#include <linux/sched.h> 
#include <linux/list.h> 

#define KTHREADD_PID 2 

static int __init ktdf_init(void) 
{ 
    struct task_struct *kthreadd_task; 
    struct list_head *list; 

    /* Find kthreadd task by PID */ 
    kthreadd_task = pid_task(find_vpid(KTHREADD_PID), PIDTYPE_PID); 
    pr_debug("Process name: %s\n", kthreadd_task->comm); 

    /* Iterate over all children of kthreadd_task */ 
    list_for_each(list, &kthreadd_task->children) { 
     struct task_struct *task; 

     /* Get next child */ 
     task = list_entry(list, struct task_struct, sibling); 
     pr_debug(" Child name: %s\n", task->comm); 
    } 

    return 0; 
} 

static void __exit ktdf_exit(void) 
{ 
} 

module_init(ktdf_init); 
module_exit(ktdf_exit); 

MODULE_AUTHOR("Sam Protsenko"); 
MODULE_DESCRIPTION("kthreadd children finder module"); 
MODULE_LICENSE("GPL"); 

因此,大家可以看到,.sibling名單circular doubly-linked list,這意味着這個列表(尾)指向第一個元素(頭)的最後一個元素。您可以從list_for_each()宏實現中看到它。

dmesg輸出(模塊由insmod加載後):

Process name: kthreadd 
    Child name: ksoftirqd/0 
    Child name: ksoftirqd/1 
    Child name: ksoftirqd/2 
    Child name: ksoftirqd/3 
    Child name: kworker/0:0 
    Child name: kworker/0:0H 
    Child name: kworker/0:1 
    Child name: kworker/0:1H 
    Child name: kworker/0:2 
    ... 

您可以通過ps命令來檢查:

$ ps auxf 

這給了我同樣的進程樹:

[kthreadd] 
\_ [ksoftirqd/0] 
\_ [ksoftirqd/1] 
\_ [ksoftirqd/2] 
\_ [ksoftirqd/3] 
\_ [kworker/0:0] 
\_ [kworker/0:0H] 
\_ [kworker/0:1] 
\_ [kworker/0:1H] 
\_ [kworker/0:2] 
... 
+0

這個解決方案正在工作,但不是2.4,因爲我沒有像更新的內核那樣的'children'列表。 我只有在問題中提到的指針。 –

+0

我終於知道你在說什麼了:[link](http:// lxr。free-electrons.com/source/include/linux/sched.h?v=2.4.37#L346)。不幸的是,我的機器上沒有內核2.4,所以即使我想出了一些代碼 - 我也無法測試它。 –

+0

我鼓勵你對你的內核進行'grep',並尋找你提到的那些指針的實際用法(也可能是「兄弟」字)。您可能也想爲此使用LXR。 –