嵌入式Linux热门培训内容之Linux内核链表

时间:2018-12-13 17:38:04

1、  内核链表文件

/linux-headers-4.4.0-112/include/linux/list.h  

/linux-headers-4.4.0-112/include/linux/types.h  

里面定义了struct list_head

         struct list_head {  

       struct list_head *next, *prev;  

};  

list_head结构包含两个指向list_head结构体的指针prev和next,由此可见,内核的链表具备双链表功能,实际上,通常它都组织成双向循环链表

2、  如何使用内核链表

2。1。 INIT_LIST_HEAD:创建链表

static inline void INIT_LIST_HEAD(struct list_head *list)

{

        list->next = list;

        list->prev = list;

}

2。2。 list_add:在链表头插入节点

static inline void __list_add(struct list_head *new,

                              struct list_head *prev,

                              struct list_head *next)

{

        next->prev = new;

        new->next = next;

        new->prev = prev;

        prev->next = new;

}

2。3。 list_add_tail:在链表尾插入节点

2。4。 list_del:删除节点

2.5. list_entry:取出节点

2.6. list_for_each:遍历链表

3、代码示例

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/init.h>

#include <linux/slab.h>

#include <linux/list.h>

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Qifa");

MODULE_DESCRIPTION("List Module");

MODULE_ALIAS("List module");

struct player

{

    char name[100];

    int num;

    struct list_head list;

};

struct player *pplayer;

struct player *tmp_player;

struct list_head player_list;

struct list_head *pos;

int mylist_init(void)

{

    int i = 0;

    INIT_LIST_HEAD(&player_list);

    pplayer = kmalloc(sizeof(struct player)*5,GFP_KERNEL);

    memset(pplayer,0,sizeof(struct player)*5);

    printk("%p %p\n",&player_list,pos); 

    for(i=0;i<5;i++)

    {

            sprintf(pplayer[i]。name,"Player%d",i+1);

        pplayer[i].num = i+1; 

        list_add( &(pplayer[i].list), &player_list);

    } 

    printk("%p %p\n",&player_list,pos); 

    list_for_each(pos,&player_list)

    {

        tmp_player = list_entry(pos,struct player,list);

        printk("<0>player %d name: %s\n",tmp_player->num,tmp_player->name);

    }

    printk("%p %p\n",&player_list,pos); 

    return 0;

}

void mylist_exit(void)

{    

    int i = 0 ;

    //list_for_each(pos,&player_list)

    {   

        printk("i = %d \n",i);

        list_del(&(pplayer[0]。list));

        list_del(&(pplayer[1].list));

        list_del(&(pplayer[2].list));

        list_del(&(pplayer[3].list));

        list_del(&(pplayer[4].list));

        i++;

    }

    printk("<0> mylist_exit\n");    

    kfree(pplayer);

}

module_init(mylist_init);

module_exit(mylist_exit);

Makefile文件

ifneq ($(KERNELRELEASE),)

obj-m := 1.o

else

KDIR := /lib/modules/$(shell uname -r)/build

all:

    make -C $(KDIR) M=$(PWD) modules

clean:

    rm -f *.ko *.o *.mod.o *.mod.c *.symvers  modul*

endif