返回
链表:双向通用链表
闲谈
2024-02-13 02:54:29
各位看官,今天咱们来聊聊链表。在学习 RTOS LiteOS 内核源码时,我们发现 LiteOS 使用的是通用链表,而 FreeRTOS 使用的是非通用链表。所以,今天我们就来探究一下链表实现的奥秘。
首先,我们先从链表的基本概念说起。链表是一种线性数据结构,由一组称为节点的元素组成。每个节点包含数据和指向下一个节点的指针。想象一下一个环形的晾衣架,每个衣服就是链表中的一个节点,而晾衣架的杆子就是链表本身。
通用链表和非通用链表有什么区别呢?通用链表中的每个节点都包含一个指向头节点的指针,而非通用链表中的节点不包含这个指针。也就是说,通用链表可以从任意节点开始遍历整个链表,而非通用链表只能从头节点开始遍历。
那么,在 RTOS 中,为什么 LiteOS 选择使用通用链表,而 FreeRTOS 使用非通用链表呢?这是因为 LiteOS 采用的是微内核架构,需要支持灵活的线程调度和内存管理。通用链表可以方便地从任意节点开始遍历,更适合这种场景。
下面,我们来举个例子,看看如何使用通用链表来管理任务队列。我们定义一个任务节点结构体,其中包含任务数据和指向下一个任务节点的指针:
typedef struct TaskNode {
Task task;
struct TaskNode *next;
} TaskNode;
然后,我们可以使用通用链表来管理任务队列:
// 任务队列头节点
TaskNode *head = NULL;
// 入队
void enqueue(TaskNode *node) {
if (head == NULL) {
head = node;
node->next = node;
} else {
node->next = head->next;
head->next = node;
}
}
// 出队
TaskNode *dequeue() {
if (head == NULL) {
return NULL;
} else if (head->next == head) {
TaskNode *node = head;
head = NULL;
return node;
} else {
TaskNode *node = head->next;
head->next = node->next;
return node;
}
}
通过使用通用链表,我们可以从任务队列中的任意节点开始遍历,这大大提高了任务调度的效率。