作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
谁能解释linux中list_for_each_entry和... entry_safe循环的工作原理。
它就像是list_for_each_entry(type *cursor, struct list_head *list, member)
list_for_each_entry_safe(type *cursor, type *next, struct list_head *list,member)
所有这些参数的作用是什么,以及如何使用它们遍历列表。
提前致谢
最佳答案
编辑:对不起,一定要晚了,我犯了很多错字。
他们真有趣! :)区别在于,如果您在迭代列表时删除某些内容,则list_for_each_entry
会中断,而list_for_each_entry_safe
不会中断(当然,这要花一些额外的CPU指令)。
尽管list.h中有一个歌唱的链表实现,但内核已经确定了双链表(我想您理解了)。您的 list 是:
struct list_head {
struct list_head *next;
struct list_head *prev;
};
next
和
prev
成员仅指向 header 自身。因此,迭代列表只是从头的
next
成员开始并调用该节点的过程,除非它与
prev
相同的地址(停止时)。否则,将调用
for
主体,并且可以使用
container_of()
宏获取指向实际结构的指针并对其进行处理。然后,在
for
的第3个字段中,我们只是移至下一个
next
。
struct list_head my_actual_list;
struct my_struct {
struct list_head node;
/* some other members */
};
/* in a function body somewhere... */
struct list_head *i;
list_for_each(i, &my_actual_list) {
struct my_struct *obj = list_entry(i, struct my_struct, node);
// do something with obj
}
list_entry
只是
container_of
的别名
struct list_head
类型的成员,而列表
的自身类型为
struct list_head
。因此,在这种情况下,谁是容器,谁是容器,仅取决于如何使用它们,但是通常,将以给定这些成员的名称来表示。迭代器的类型为
struct list_head *
。这是一个示例,我将用它们的等效代码替换普通的函数和宏调用:
struct my_container {
struct list_head list;
int some_member;
/* etc. */
};
struct my_obj {
struct list_head node;
int some_member;
/* etc. */
};
void func() {
struct my_container container;
struct my_obj obj1, obj2;
struct list_head *i;
/* INIT_LIST_HEAD(&container.list); */
container.list.next = &container.list;
container.list.prev = &container.list;
/* list_add_tail(&obj1.node); */
container.list.prev = &obj1.node;
obj1.node.next = &container.list;
obj1.node.prev = &container.list;
container.list.next = &obj1.node;
/* list_add_tail(&obj2.node); */
container.list.prev = &obj2.node;
obj2.node.next = &container.list;
obj2.node.prev = &obj1.node;
obj1.node.next = &obj2.node;
/* list_for_each(i, &container.list) { */
for (i = container.list.next; i != &container.list; i = i->next) {
struct my_obj *obj = list_entry(i, struct my_obj, node);
/* do stuff */
}
}
关于list - 说明list_for_each_entry和list_for_each_entry_safe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16230524/
我是一名优秀的程序员,十分优秀!