利用 Linux 内核提供的链表机制创建一个链表

Posted Jiamings

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用 Linux 内核提供的链表机制创建一个链表相关的知识,希望对你有一定的参考价值。

linux 内核提供的链表接口函数定义在 include/linux/list.h 中

main.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "list.h"

struct num // 封装的自己的数据结构
int i;
struct list_head list; // 将链表的操作以及组织完全交由内核提供的工具
;

int main(int argc, char **argv)
LIST_HEAD(test_list); // 链表头结点 test_list
/*
#define LIST_HEAD_INIT(name) &(name), &(name)
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
*/
int i;
struct num *num; // 声明变量
struct num *num1;

srand((unsigned)time(NULL));

/* Add */
printf("add 100 element into list\\n");
for (i = 0; i < 100; i++)
num = (struct num*)malloc(sizeof(struct num)); // 创建了一个节点
num->i = i;
list_add_tail(&num->list, &test_list); // new entry to be added,list head to add it before 头插法


i = 0;
/* print list */
printf("printf the list\\n");
list_for_each_entry(num, &test_list, list)
printf("%2d ", num->i);
if ((i+1)%10 == 0)
printf("\\n");
i++;

printf("\\n");

/* Delete */
list_for_each_entry_safe(num, num1, &test_list, list)
list_del(&num->list);
free(num);


if (list_empty(&test_list))
printf("Free test_list successfully\\n");

return 0;

list.h

static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)

if (!__list_add_valid(new, prev, next))
return;

next->prev = new;
new->next = next;
new->prev = prev;
WRITE_ONCE(prev->next, new);

static inline void list_add(struct list_head *new, struct list_head *head)

__list_add(new, head, head->next);

static inline void list_add_tail(struct list_head *new, struct list_head *head) // 新节点,头结点

__list_add(new, head->prev, head);
static inline void __list_del(struct list_head * prev, struct list_head * next)

next->prev = prev;
WRITE_ONCE(prev->next, next);

static inline void __list_del_entry(struct list_head *entry)

if (!__list_del_entry_valid(entry))
return;

__list_del(entry->prev, entry->next);

static inline void list_del(struct list_head *entry)

__list_del_entry(entry);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry(pos, head, member) \\
for (pos = list_first_entry(head, typeof(*pos), member); \\
&pos->member != (head); \\
pos = list_next_entry(pos, member))
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)

return READ_ONCE(head->next) == head;


以上是关于利用 Linux 内核提供的链表机制创建一个链表的主要内容,如果未能解决你的问题,请参考以下文章

Linux 内核 内存管理RCU 机制 ① ( RCU 机制简介 | RCU 机制的优势与弊端 | RCU 机制的链表应用场景 )

Linux 内核 内存管理RCU 机制 ② ( RCU 机制适用场景 | RCU 机制特点 | 使用 RCU 机制保护链表 )

Linux 内核 内存管理RCU 机制 ② ( RCU 机制适用场景 | RCU 机制特点 | 使用 RCU 机制保护链表 )

Linux内核-链表

Linux内核(10) - 内核中的链表

Linux 内核通知链机制的原理及实现