首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux list_head

list_head 是 Linux 内核中的一个重要数据结构,用于实现双向循环链表。以下是对 list_head 的基础概念、优势、类型、应用场景以及可能遇到的问题和解决方案的详细解释:

基础概念

list_head 是一个简单的结构体,定义如下:

代码语言:txt
复制
struct list_head {
    struct list_head *next, *prev;
};

它包含两个指针,分别指向前一个节点和后一个节点,从而形成一个双向链表。

优势

  1. 简洁高效list_head 结构体非常小,只有两个指针,占用内存少。
  2. 通用性强:可以嵌入到任何结构体中,使其具有链表的功能。
  3. 双向循环:支持双向遍历和循环遍历,使用方便。

类型

list_head 本身是一个通用的链表节点结构体,但可以通过宏和函数来操作不同类型的链表。

应用场景

list_head 广泛应用于 Linux 内核中,例如:

  • 文件系统中的 inode 链表
  • 进程管理中的任务队列
  • 网络协议栈中的数据包队列

可能遇到的问题及解决方案

1. 链表初始化问题

问题:未正确初始化 list_head 导致链表操作异常。

解决方案:使用 INIT_LIST_HEAD 宏初始化链表头。

代码语言:txt
复制
struct list_head my_list;
INIT_LIST_HEAD(&my_list);

2. 插入和删除节点问题

问题:插入或删除节点时未正确更新前后节点的指针,导致链表断裂或循环。

解决方案:使用内核提供的链表操作函数,如 list_addlist_del 等。

代码语言:txt
复制
struct list_head new_node;
INIT_LIST_HEAD(&new_node);

// 在链表头插入新节点
list_add(&new_node, &my_list);

// 删除节点
list_del(&new_node);

3. 遍历链表问题

问题:遍历链表时未正确处理空链表或单节点链表。

解决方案:使用 list_for_each 宏进行安全遍历。

代码语言:txt
复制
struct list_head *pos;
struct my_struct *entry;

list_for_each(pos, &my_list) {
    entry = list_entry(pos, struct my_struct, list);
    // 处理 entry
}

示例代码

以下是一个完整的示例,展示如何使用 list_head 实现一个简单的链表:

代码语言:txt
复制
#include <linux/list.h>
#include <stdio.h>

struct my_struct {
    int data;
    struct list_head list;
};

int main() {
    struct list_head my_list;
    INIT_LIST_HEAD(&my_list);

    // 创建并插入节点
    struct my_struct *entry1 = malloc(sizeof(struct my_struct));
    entry1->data = 1;
    INIT_LIST_HEAD(&entry1->list);
    list_add(&entry1->list, &my_list);

    struct my_struct *entry2 = malloc(sizeof(struct my_struct));
    entry2->data = 2;
    INIT_LIST_HEAD(&entry2->list);
    list_add(&entry2->list, &my_list);

    // 遍历链表
    struct list_head *pos;
    list_for_each(pos, &my_list) {
        struct my_struct *entry = list_entry(pos, struct my_struct, list);
        printf("Data: %d\n", entry->data);
    }

    // 删除节点
    list_del(&entry1->list);
    free(entry1);
    list_del(&entry2->list);
    free(entry2);

    return 0;
}

通过以上解释和示例代码,你应该对 list_head 有了全面的了解,并能够在实际开发中正确使用它。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

002 Linux内核中双向链表的经典实现

概要 本文对双向链表进行探讨,介绍的内容是Linux内核中双向链表的经典实现和用法。其中,也会涉及到Linux内核中非常常用的两个经典宏定义offsetof和container_of。...内容包括: 1.Linux中的两个经典宏定义 2.Linux中双向链表的经典实现 Linux中的两个经典宏定义 倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of...1.offsetof 1.1 offsetof介绍 定义:offsetof在linux内核的include/linux/stddef.h中定义。...Linux中双向链表的经典实现 1.Linux中双向链表介绍 Linux双向链表的定义主要涉及到两个文件: include/linux/types.h include/linux/list.h Linux...1 struct person 2 { 3 int age; 4 char name[20]; 5 struct list_head list; 6 }; 2.Linux

1.8K20
  • Linux内核中双向链表的经典实现

    概要 本文对双向链表进行探讨,介绍的内容是Linux内核中双向链表的经典实现和用法。其中,也会涉及到Linux内核中非常常用的两个经典宏定义offsetof和container_of。...内容包括: 1.Linux中的两个经典宏定义 2.Linux中双向链表的经典实现 Linux中的两个经典宏定义 倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of...1.offsetof 1.1 offsetof介绍 定义:offsetof在linux内核的include/linux/stddef.h中定义。...Linux中双向链表的经典实现 1.Linux中双向链表介绍 Linux双向链表的定义主要涉及到两个文件: include/linux/types.h include/linux/list.h Linux...1 struct person 2 { 3 int age; 4 char name[20]; 5 struct list_head list; 6 }; 2.Linux

    2.7K30

    Linux内核链表的使用

    /******************** * 内核中链表的应用 ********************/ (1)介绍 在Linux内核中使用了大量的链表结构来组织数据,包括设备列表以及各种功能模块中的数据组织...这些链表大多采用在include/linux/list.h实现的一个相当精彩的链表数据结构。...和以前介绍的双链表结构模型不同,这里的list_head没有数据域。在Linux内核链表中,不是在链表结构中包含数据,而是在数据结构中包含链表节点。...如: struct my_struct{ struct list_head list; unsigned long dog; void *cat; }; linux中的链表没有固定的表头,从任何元素开始访问都可以...定义在linux/list.h> a.增加节点 list_add(struct list_head *new, struct list_head *head); 向指定链表的head

    2.3K30

    linux内核源码 -- list链表

    linux kernel中的list估计已经被各位前辈们写烂了,但是我还是想在这里记录一下; linux kernel里的很多数据结构都很经典, list链表就是其中之一 本篇要介绍的内容: list...的定义 list提供的操作方法 注意事项 使用实例 ---- List 所在文件: List的所有操作可以在 include/linux/list.h找到; List head的定义可以在 include.../linux/types.h找到; 定义 实际上这就是一个双向循环链表, 且有一个头指针 list head的定义: struct list_head { struct list_head *next...*list, struct list_head *head, struct list_head *entry) { struct list_head *new_first =...struct中,这个宏就是由这个list_head ptr来获取当前所处的struct对象的指针, 用了linux的经典宏定义 container_of #define list_entry(ptr,

    2.4K10

    内存分配算法 伙伴系统

    伙伴系统是常用的内存分配算法,linux内核的底层页分配算法就是伙伴系统,伙伴系统的优点就是分配和回收速度快,减少外部碎片。...然后又看了一下linux4.8的buddy system实现,linux的buddy system主要进行page分配也是linux最底层的分配,其他的分配算法都是以这个分配为基础,在x86架构下一个page...linux对内存进行了分区包括低端内存区,高端内存区,dma区,而且还对numa架构做了很多处理,对页面也进行了分类,这些不是讨论的重点,现在主要是提取linux的buddy算法,只提取核心部分,可以在控制台下运行...最大的是10,也就是1024个基本单位,所以linux在x86下一次最多可分配4MB内存。  .../** *删除节点,并且将next和prev置空,linux内核中是指向一个指定的地址 */ static inline void list_del_entry(struct list_head

    1.6K10

    Linux下基于TCP协议的群聊系统设计(多线程+select)

    一、功能介绍 这是基于Linux下命令行设计的一个简单的群聊天程序。...这个例子可以学习、巩固Linux下网络编程相关知识点 练习Linux下socket、TCP编程 练习Linux下pthread、线程编程 练习Linux下多路IO检测、select函数使用 练习C语言链表使用...好友上线通知、正常聊天效果: 好友下线提示: 二、select函数功能、参数介绍 在linux命令行可以直接man查看select函数的原型、头文件、帮助、例子 相关信息。...Linux下监听文件描述符状态的函数有3个:select、poll、epoll,这3个函数都可以用在socket网络编程里监听客户端、服务器的状态。...CLIENT_FD *list_head); void Server_SendMsgData(struct CLIENT_FD *list_head,struct MSG_DATA *msg_data

    1.2K30

    【Linux 内核 内存管理】RCU 机制 ④ ( RCU 模式下更新链表项 list_replace_rcu 函数 | 链表操作时使用 smp_wmb() 函数保证代码执行顺序 )

    模式下更新链表项 list_replace_rcu 函数 二、链表操作时使用 smp_wmb() 函数保证代码执行顺序 一、RCU 模式下更新链表项 list_replace_rcu 函数 ---- 在 Linux...源码 linux-5.6.18\include\linux\rculist.h 头文件中定义的就是 RCU 链表的操作 , 其中定义的 static inline void list_replace_rcu...(struct list_head *old, struct list_head *new) 函数 , 就是 更新 链表元素 的 函数 ; list_replace_rcu 函数中 , 更新链表元素的核心操作就是将...* Note: @old should not be empty. */ static inline void list_replace_rcu(struct list_head *old,...struct list_head *new) { new->next = old->next; new->prev = old->prev; rcu_assign_pointer(list_next_rcu

    79520

    一文搞懂 Linux 内核链表(深度分析)

    在 Linux 内核中使用最多的数据结构就是链表了,其中就包含了许多高级思想。 比如面向对象、类似C++模板的实现、堆和栈的实现。 1....内核链表 在Linux内核中使用了大量的链表结构来组织数据,包括设备列表以及各种功能模块中的数据组织。这些链表大多采用在[include/linux/list.h]实现的一个相当精彩的链表数据结构。...当 list1 被挂接到 list2 之后,作为原表头指针的 list1 的next、prev仍然指向原来的节点,为了避免引起混乱,Linux提供了一个list_splice_init()函数.该函数在将...list_head *list, struct list_head *head); 示意图如下: ?...总结 本文详细分析了 linux 内核 中的双链表结构,以图文的方式旨在帮助大家理解。

    8.6K77

    如何移植并使用Linux内核的通用链表(附完整代码实现)

    在实际的工作中,我们可能会经常使用链表结构来存储数据,特别是嵌入式开发,经常会使用linux内核最经典的双向链表 list_head。...本篇文章详细介绍了Linux内核的通用链表是如何实现的,对于经常使用的函数都给出了详细的说明和测试用例,并且移植了Linux内核的链表结构,在任意平台都可以方便的调用内核已经写好的函数。...Linux内核中的链表   上面介绍了普通链表的实现方式,可以看到数据域都是包裹在节点指针中的,通过节点指针访问下一组数据。...但是 Linux内核的链表实现可以说比较特殊,只有前驱和后继指针,而没有数据域。链表的头文件是在include/list.h(Linux2.6内核)下。.../* * @Description: 移植Linux2.6内核list.h * @Version: V1.0 * @Autor: https://blog.csdn.net/qq_16933601

    1.5K20
    领券