內核常見函數之list_for_each_entry/container_of

原文地址:http://blog.163.com/kmustchenb@126/blog/static/1109057652011112221829306/

一、list_for_each

1.list_for_each原型
#define list_for_each(pos, head) \
    for (pos = (head)->next, prefetch(pos->next); pos != (head); \
    pos = pos->next, prefetch(pos->next))
它實際上是一個 for 循環,利用傳入的pos 作爲循環變量,從表頭 head開始,逐項向後(next方向)移動 pos ,直至又回到 head (prefetch() 可以不考慮,用於預取以提高遍歷速度)。
注意:此宏必要把list_head放在數據結構第一項成員,至此,它的地址也就是結構變量的地址。

2.使用方法(以訪問當前進程的子進程爲例):

struct list_head {
 struct list_head *next, *prev;
};

在struct task_struct 中有如下定義:
struct list_head children;

所以

struct task_struct *task;

struct list_head *list;

list_for_each(list,&current->chilidren) {

              task = list_entry(list, struct task_struct, sibling);/*task指向當前的某個子進程*/

}

其中用到了函數list_entry():
這個函數的作用在圖1中表示就是可以通過已知的指向member子項的指針,獲得整個結構體的指針(地址)
#define list_entry(ptr, type, member) \
 
       container_of(ptr, type, member)

二、list_for_each_entry:
在Linux內核源碼中,經常要對鏈表進行操作,其中一個很重要的宏是list_for_each_entry:
意思大體如下:
假設只有兩個結點,則第一個member代表head,
list_for_each_entry的作用就是循環遍歷每一個pos中的member子項。
圖1:
pos: 
                                                         pos:
___________ 
                                      ____________
                                                                                 |
                                                                                 |
  ...........                                             ................       |
                                          

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章