/*** list_add - add a new entry* @new: new entry to be added* @head: list head to add it after** Insert a new entry after the specified head.* This is good for implementing stacks.*/staticinlinevoidlist_add(structlist_head*new,structlist_head*head){__list_add(new,head,head->...
static inline void list_splice(struct list_head *list, struct list_head *head); 假设当前有两个链表,表头分别是list1和list2(都是struct list_head变量),当调用list_splice(&list1,&list2)时,只要list1非空,list1链表的内容将被挂接在list2链表上,位于list2和list2.next(原list2表的第一个节点)之间。
1. 链表数据结构 list_head 的定义: structlist_head{ structlist_head*next,*prev; }; 1. 2. 3. 【注意】只有前后节点指针,没有数据! 2. 链表的声明和初始化 2.1静态方法——编译时 #define LIST_HEAD_INIT(name) { &(name), &(name) } // 链表的pre和next指针都指向了节点自己的首地址 #define...
2. #define LIST_HEAD(name) \ 3. struct list_head name = LIST_HEAD_INIT(name) 4. static inline void INIT_LIST_HEAD(struct list_head *list) 5. { 6. WRITE_ONCE(list->next, list); 7. list->prev = list; 8. } 所以可以通过这个方法来初始化一个链表,如下是将listhead作为一个结构体...
structlist_head{ structlist_head*next,*prev; }; 使用方法就是将list_head以成员变量的形式添加到其他数据结构中。 假设现有一群学生在排队 structstudent{ char*name; intage; structlist_nodeothers; } 获取同学S其前面一位同学的方式为S->others.next,是不是很简单?
struct list_head node; }; 将实参代入 offset( struct file_node, node );最终将变成这样: ( (size_t) & ((struct file_node*)0)-> node );这样看的还是不很清楚,我们再变变: struct file_node *p = NULL; & p->node; 这样应该比较清楚了,即求 p 的成员 node的地址,只不过p 为0地址,从0地...
structlist_head *plist = &hello.list; printf("&hello = %x\n", (char*)plist - (unsignedlong) 8 )); 而这种方式就是list_head的用法, 它是专门用来当作别的结构的元素,只要我们得到这个元素的位置和包含这个元素的结构是哪一种, 我们可以很轻易的算出包含此元素的结构地址,linux给我们提供了这样一个...
这里说明一下,WRITE_ONCE(list->next, list)的本质就是list->next = list,也就是说,INIT_LIST_HEAD函数的作用就是将list_head的两个指针均指向自身。 使用WRITE_ONCE这个宏的作用主要是解决并行程序中的变量访问问题,这里不再过多解释,感兴趣的可以阅读这篇博客。
在Linux内核中,对于数据的管理,提供了2种类型的双向链表:一种是使用list_head结构体构成的环形双向链表;另一种是使用hlist_head和hlist_node2个结构体构成的具有表头的链型双向链表。 list_head的结构体如下所示: 代码语言:javascript 复制 struct list_head{struct list_head*next,*prev;}; ...