嵌入式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

? 江苏快3号码表