Linux嵌入式 -- 内核 - 内核链表

1. linux内核链表

链表数据结构的定义:
struct list_head 

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

2. 链表操作

Linux内核中提供的链表操作主要有:
初始化链表头
INIT_LIST_HEAD(list_head*head) 
插入节点
list_add(struct list_head *new, struct list_head *head)  (链表头head之后插入节点)
list_add_tail(struct list_head *new, struct list_head *head)   它是从右向左在head->priv和head两个节点之间插入_new。

 删除节点

list_del(struct list_head *entry)
提取数据结构
list_entry(ptr, type, member)

已知数据结构中的节点指针ptr,找出数据结构,type为整个节点结构的类型,member为list_head在整个节点结构中的成员名,返回一个指向节点类型的指针,例:list_entry(P, struct h,M)。


遍历    list_for_each(struc list_head *pos, struc list_head *head)
例:
structlist_head *entry;
structlist_head cs46xx_devs;  //链表头
list_for_each(entry, &cs46xx_devs)  //内核定义实际为or循环
{
    card =list_entry(entry, struct cs_card, list);
    if (card->dev_midi == minor)
        break;
}


3. 示例代码

#include<linux/list.h>
#include<linux/slab.h>
struct student
{
	char name[100];
	int num;
	struct list_head list;
};

struct student *pstudent;
struct student *tmp_student;
struct list_head student_list;
struct list_head *pos;

int mylist_init()
{
	int i=0;
	INIT_LIST_HEAD(&student_list);

	pstudent = kmalloc( sizeof(struct student)*5, GFP_KERNEL );
	memset( pstudent, 0, sizeof(struct student)*5 );

	for(i=0; i<5; i++)
	{
		sprintf(pstudent[i].name, "student%d", i+1);
		pstudent[i].num = i+1;
		list_add( &(pstudent[i].list), &student_list );   //插入链表
	}

	list_for_each( pos, &student_list )
	{
		tmp_student = list_entry(pos, struct student, list);   
		printk("<0>student %d name: %s\n", tmp_student->num, tmp_student->name); // 5-->1输出, 注意list_add 与 list_add_tail区别。。
	}
	return 0;	
}

void mylist_exit()
{
	int i=0;
	for(i=0; i<5; i++)
	{
		list_del(&(pstudent[i].list));
	}
	kfree(pstudent);
}

module_init(mylist_init);
module_exit(mylist_exit);

 内核编译makefile

ifneq ($(KERNELRELEASE),)

obj-m :=list.o

else

KDIR := /lib/modules/3.5.0-17-generic/build
all: 
    make -C $(KDIR) M=$(PWD) modules
clean:
    rm -f *.ok *.o *.mod.o *.mod.c *.symvers
endif



posted @ 2013-08-09 22:41  今晚打酱油_  阅读(212)  评论(0编辑  收藏  举报