【问题标题】:Correct way to join two double linked list加入两个双链表的正确方法
【发布时间】:2016-02-24 08:55:51
【问题描述】:

在Linux内核源码中,list_splice是用__list_splice实现的:

static inline void __list_splice(const struct list_head *list,
                                 struct list_head *prev,
                                 struct list_head *next)
{
        struct list_head *first = list->next; // Why?
        struct list_head *last = list->prev;

        first->prev = prev;
        prev->next = first;

        last->next = next;
        next->prev = last;
}

list 不是已经指向链表的头部了吗? 为什么我们需要取而代之的是list->next

【问题讨论】:

  • 如果它被这样使用,那么列表头可能不是实际的列表节点。

标签: c linux-kernel linked-list


【解决方案1】:

Linux内核中的双链表API是作为循环列表的抽象实现的。在那个简单的方案中,HEAD 节点 包含任何有效负载(数据)并明确用于保持列表的起点。由于这样的设计,a) 检查列表是否为空,b) 调试列表非常简单,因为未使用的节点已分配给所谓的 POISON — 仅特定于列表指针的幻数整个内核。

1) 未初始化列表

+-------------+
|    HEAD     |
| prev | next |
|POISON POISON|
+-------------+

2) 空列表

+----------+-----------+
|          |           |
|          |           |
|   +------v------+    |
|   |    HEAD     |    |
+---+ prev | next +----+
    | HEAD   HEAD |
    +-------------+

3) 一个元素的列表

+--------------+--------------+
|              |              |
|              |              |
|       +------v------+       |
|       |    HEAD     |       |
|   +---+ prev | next +--+    |
|   |   |ITEM1   ITEM1|  |    |
|   |   +-------------+  |    |
|   +--------------------+    |
|              |              |
|       +------v------+       |
|       |    ITEM1    |       |
+-------+ prev | next +-------+
        |    DATA1    |
        +-------------+

4) 列表中的两个项目

      +----------+
      |          |
      |          |
      |   +------v------+
      |   |    HEAD     |
   +------+ prev | next +----+
   |  |   |ITEM2   ITEM1|    |
   |  |   +-------------+    |
+----------------------------+
|  |  |          |
|  |  |   +------v------+
|  |  |   |    ITEM1    |
|  |  +---+ prev | next +----+
|  |  |   |    DATA1    |    |
|  |  |   +-------------+    |
|  +-------------------------+
|     |          |
|     |   +------v------+
|     |   |    ITEM2    |
+---------+ prev | next +----+
      |   |    DATA2    |    |
      |   +-------------+    |
      |                      |
      +----------------------+

在无锁算法中,只有 next 指针才能保证一致。保证并非总是如此。提交2f073848c3cc 介绍了它。

【讨论】:

    猜你喜欢
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多