物联网
您现在所在的位置:首页>企业动态>物联网

Linux 内核链表的使用及深入分析,Linux 内核中的链表原理实践

编辑:学到牛牛IT培训    发布日期: 2021-12-27 11:30:13  

Linux内核链表的设计初衷是为了解决不同数据类型作为链表数据节点对函数接口和封装的影响。比如以struct cat和struct dog分别形成两条链表的话,它们的接口函数(插入、删除、遍历等)都需要依赖它们自己的类型,这使得我们不得不反复的根据类型修改链表的接口函数。

Linux内核链表设计时将链表的链独立出来(struct list_head),链表的接口函数就不会受到具体节点数据影响。比如我们设计一个以struct dog的结构为链表。

常规设计:

struct dog{
        unsigned short color;
        char name[20];
        struct dog *next, *prev;
};
// 在链表开头插入新节点
void insertHead( struct dog **h, struct dog *n )
{
        n->next = *h;
        if( *h != NULL ){
                (*h)->prev = n;
}
*h = n;
}

Linux常规链表设计.png

图 1 常规链表设计

Linux内核链表设计:

struct list_head{
        struct list_head *next, *prev;
};
struct dog{
        unsigned short color;
        char name[20];
        struct list_head lists;
};
// 在链表开头插入新节点
void insertHead( struct list_head **h, struct list_head *n )
{
        n->next = *h;
        if( *h != NULL ){
                (*h)->prev = n;
}
*h = n;
}

Linux内核链表设计.png

图 2 内核链表设计

如上示例代码和图可见,常规链表设计节点数据类型和链表操作函数耦合性高,当类型发生变化,链表操作函数必须重新实现。而内核链表设计可以有效避免上述弊端,它的链的操作和具体节点数据类型没有任何关系。内核链表的设计解决的链表接口一致问题,但是却出现的访问问题。从内核链表头指针出发,我们只能访问到struct list_head类型(图2中底色为橘色部分)。为了解决访问问题,我们就设计了一个非常经典的宏定义container_of,具体定义如下:

#define container_of( ptr, type, member )
                (type *)( (char *)ptr – (unsigned long)&((type*)0)->member )

container_of的核心含义是:已知结构体对象中任何一个成员的地址,可以找到结构体对象的首地址。所以根据container_of我们可以找到图2中整个节点的首地址。测试代码如下:

int main()
{
        struct list_head *head = NULL;
        int i = 0;
        while( i < 5 ){
                struct dog *d = malloc( sizeof( struct dog ) );
                d->lists.next = NULL;
                d->lists.prev = NULL;
                d->color = rand() % 0xffffff;
                sprintf( d->name, "wangcai%d", i );
                insertHead( &head, &d->lists );
            i++;
        }
        struct list_head *p = head;
        while( p != NULL ){
                struct dog *t = container_of( d, struct dog, lists );
                printf( "t->name = %s, t->color = %x ", t->name, t->color );
                p = p->next;
        }
        return 0;
}

免费试学
课程好不好,不如实地听一听

推荐阅读

  • 计算机专业的就业难度怎么样?

    国产午夜鲁丝片AV无码蜜臀,福利免费观看午夜体检区,人妻少妇精品无码专区APP,伊人久久大香线蕉成人综合网,国产妓女在线观看视频,亚洲成a人片在线观看尤物,亚洲精品国产一二三无码AV,亚汌国产一区二区三区

  • 嵌入式软件开发学习路线

    国产午夜鲁丝片AV无码蜜臀,福利免费观看午夜体检区,人妻少妇精品无码专区APP,伊人久久大香线蕉成人综合网,国产妓女在线观看视频,亚洲成a人片在线观看尤物,亚洲精品国产一二三无码AV,亚汌国产一区二区三区

  • 为什么自学编程那么难?

    国产午夜鲁丝片AV无码蜜臀,福利免费观看午夜体检区,人妻少妇精品无码专区APP,伊人久久大香线蕉成人综合网,国产妓女在线观看视频,亚洲成a人片在线观看尤物,亚洲精品国产一二三无码AV,亚汌国产一区二区三区

  • IT培训机构出来的到底好不好就业呢?

    国产午夜鲁丝片AV无码蜜臀,福利免费观看午夜体检区,人妻少妇精品无码专区APP,伊人久久大香线蕉成人综合网,国产妓女在线观看视频,亚洲成a人片在线观看尤物,亚洲精品国产一二三无码AV,亚汌国产一区二区三区

封闭学习

2

1

028-61775817

蜀ICP备2021001672号

在线咨询 免费试听VIP课程