内核的list"/>
Linux内核的list
list_head是Linux内核中使用最广泛的双向链表,每个节点都可以为任意类型,可以作为栈或队列使用,没有读过Linux内核的同学应该是没见过如此有创意的链表。
今天对linux内核中的list_head稍作修改,以便民用,不再是军用专属。
申明:本来很久没写代码了,没装任何IDE环境,所涉及到的代码不保证正确。今天只是蛋疼
直接上代码:
list_head.h
/***************************************************************************************************
*
* Linux的list_head链表民用改造
*
****************************************************************************************************
*
* 文 件:list_head.h
*
* 功能描述:
* 1. 大多数情况C码农们可能对不同数据类型需要创建不同类型的链表,使得代码量增加及运行时内存
* 的消耗增加。
* 2. Linux内核中有一个叫list_head的双向链表,各种总线驱动都使用list_head进行driver与device
* 之间的匹配,然后加载相应的驱动
* 3. 由于list_head可以挂任意类型的节点,因此每个节点对应的结构体中必须包含一个list_head类型
* 的成员,无其他要求。
*
* 创建日期:2016.12.29
* 作 者:oneonce
* 版 本:v1.00.000
*
***************************************************************************************************/#ifndef __LIST_HEAD_H__
#define __LIST_HEAD_H__#ifdef c__plusplusextern "c"{
#endif/***************************************************************************************************
使用方法:struct test_node
{int value;list_head_t h;// 需要添加到list_head_t类型的列表节点结构体必须包含一个list_head_t成员
};void test()
{list_head_t my_list;list_head_t *entry = NULL;test_node a, b, c;list_head_init(&my_list);a.value = 1;b.value = 2;c.value = 3;#if 0 // 压栈操作(列表作为栈使用)list_push_stack(&a.h, &my_list);// a压栈list_push_stack(&b.h, &my_list);// b压栈list_push_stack(&c.h, &my_list);// c压栈
#else // 入列操作(列表作为队列使用)list_enqueue(&a.h, &my_list);// a入列list_enqueue(&b.h, &my_list);// b入列list_enqueue(&c.h, &my_list);// c入列
#endifint size = list_size(&my_list);// 列表大小list_for_each(entry, &my_list){test_node *node = list_entry(entry, struct test_node, h);printf("node value: %d\n", node->value);}#if 0 // 出栈操作(列表作为栈使用)entry = list_pop_stack(&a.h, &my_list);// a出栈//entry = list_pop_stack(&b.h, &my_list);// b出栈//entry = list_pop_stack(&c.h, &my_list);// c出栈
#else // 出列操作(列表作为队列使用)entry = list_dequeue(&a.h, &my_list);// a出列entry = list_dequeue(&b.h, &my_list);// b出列entry = list_dequeue(&c.h, &my_list);// c出列
#endiftest_node *node = list_entry(entry, struct test_node, h);// 很关键。也是list_head最巧妙的地方,根据指向结构体中list_head成员的指针得到指向结构体的指针(自定义的结构体)printf("出栈/出列node value: %d\n", node->value);list_revese(&my_list);// 列表倒置
}***************************************************************************************************/#define offsetof(TYPE, MEMBER) (((size_t)&(TYPE *)0)->MEMBER)// 得到结构体成员在结构体中的偏移量
#define container_of(ptr, type, member) ((type *)((char *)ptr - offsetof(type, member)))// 得到指向结构体指针的首地址
#define list_for_each(pos, head) for (pos = (head)->next; pos != (head); pos = pos->next)// for循环
#define list_for_each_r(pos, head) for (pos = (head)->prev; pos != (head); pos = pos->prev)// 反向for循环
#define list_entry(ptr, type, member) (NULL == ptr)? NULL : container_of(ptr, type, mem
更多推荐
Linux内核的list
发布评论