linux驱动里面双向链表
在驱动开发,或者linux内核,里面有很多双向队列的使用。
里面自己简单自己模仿写了一下代码,记录双向队列的实现。
include <stdio.h>
include<stdlib.h>
define offsetof(type,member) (int)(&((type *)0)->member)
if 1
define container_of(ptr,type,member) ({ \
const char* __mptr = (ptr); \
(type *)(((char *)__mptr) - offsetof(type,member)); \
})
else
define container_of(ptr, type, member) ({ \
const char* __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
endif
struct list_head {
struct list_head* prev;
struct list_head* next;
};
//初始化,就是让next和prev指向head自己。在判断链表结束的时候, 就是看next是否指向head.指向head,说明链表已经遍历完成
define list_init(head) \
((struct list_head *)head)->prev = head;
((struct list_head *)head)->next=head;
define list_entry(ptr, type, member) container_of(ptr, type, member)
define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); &pos->member != (head); pos = list_entry(pos->member.next, typeof(*pos), member))
void list_add_head(struct list_head* new_node, struct list_head* head);
//因为是非空的双向队列,head这个元素是一直存在的。
//头部插入
void list_add_head(struct list_head* new_node, struct list_head* head)
{
struct list_head* next = head->next;//知道head 指向的第一个元素
next->prev = new_node; //新元素,插入在头部,所以之前head指向的第一个元素,就需要指向new的节点
new_node->next = next;//新元素的next指向了之前head指向的第一个元素
new_node->prev = head;//新元素的prev指向了head
head->next = new_node;//head的next,就需要指向新的元素。
}
//尾部插入
void list_add_tail(struct list_head* new_node, struct list_head* head)
{
struct list_head* prev = head->prev; //知道head 指向的第后一个元素
prev->next = new_node; //最后一个元素的next,指向这个新的元素
new_node->prev = head->prev;//new元素,的prev,指向之前的最后一个元素,就head->prev指向的元素
new_node->next = head; //new元素,next,z指向了head
head->prev = new_node; //head元素的prev,就需要指向新的元素了
}
void list_del(struct list_head *old_node)
{
old_node->prev->next = old_node->next;
old_node->next->prev = old_node->prev;
}
struct list_test {
int cnt;
struct list_head head;
};
int main(int argc, char* argv[])
{
struct list_test mytest;
list_init(&mytest.head);
for (int i = 0;i < 5;i++) {
struct list_test* p = (struct list_test*)malloc(sizeof(struct list_test));
p->cnt = i+10;
//list_add_head(&p->head, &mytest.head);
list_add_tail(&p->head, &mytest.head);
}
struct list_test* p;
struct list_head * t=mytest.head.next;
while(t != &mytest.head)
{
p = container_of(t, struct list_test, head);
printf("%d\n",p->cnt);
t = t->next;
}
list_for_each_entry(p,&mytest.head,head) {
if(p->cnt == 13)
list_del(&p->head);
}
list_for_each_entry(p,&mytest.head,head) {
printf("%d\n",p->cnt);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库