#include
#include
#include
#include
#include
struct student
{
char name[100];
int num;
struct list_head list;
};
struct student *pstudent;
struct student *tmp_student;
//定义一个链表头.
struct list_head student_list;
//list_head 指针. 指向每一个节点
struct list_head *pos;
int mylist_init(void)
{
int i = 0;
printk("offsetof(name):%d\n",offsetof(struct student, name));
printk("offsetof(num):%d\n",offsetof(struct student, num));
printk("offsetof(list):%d\n",offsetof(struct student, list));
printk("sizeof(student):%d\n",sizeof(struct student));
INIT_LIST_HEAD(&student_list);
pstudent = kmalloc(sizeof(struct student)*5,GFP_KERNEL);
memset(pstudent,0,sizeof(struct student)*5);
//一次添加5个节点
for(i=0;i<5;i++) {
sprintf(pstudent[i].name,"Student%d",i+1);
pstudent[i].num = i+1;
#if 0
list_add_tail( &(pstudent[i].list), &student_list);
#else
list_add( &(pstudent[i].list), &student_list);
#endif
}
//从前往后遍历. 获取有效的pos(list)
list_for_each(pos,&student_list) {
//通过list来偏移到结构提的首地址.
tmp_student = list_entry(pos,struct student,list);
printk("student %d name: %s\n",tmp_student->num,tmp_student->name);
}
return 0;
}
void mylist_exit(void)
{
int i ;
for(i=0;i<5;i++) {
list_del(&(pstudent[i].list));
}
kfree(pstudent);
}
module_init(mylist_init);
module_exit(mylist_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("list@whpe");
MODULE_DESCRIPTION("List Module");
/************************************************************************
struct list_head {
struct list_head *next, *prev;
};
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
_list_add(新节点newnode, newnode->pre节点, newnode->next节点);
所以list_add_tail----(new, head->prev, head)
所以list_add---------(new, head, head->next)
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;
}
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
//从前往后遍历.
#define list_for_each(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = pos->next)
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
//typeof:获得数据的类型
//本来指向list的指针,通过这个宏,就可以指向strcut student的指针了. 通过偏移.
// char * (&list) - 104 ------>指向了.char *name的位置了.
tmp_student = list_entry(pos,struct student,list);
struct student
{
char name[100];
int num;
struct list_head list;
};
******************************************************************************/
代码下载地址:
https://download.csdn.net/download/u010550992/10384422