前一篇文章討論了list_head 結構的基本結構和實現原理,本文主要介紹一下實例代碼。
自己如果想在應用程序中使用list_head 的相應操作(當然應該沒人使用了,C++ STL提供了list 用起來貌似更方便), 在應用程序中需要包含自己的 "list.h" 頭文件:
/* 注:這個list.h 是為了配合示例程序而建的,內容來自:linux/include/linux/list.h 和相關文件 */ #ifndef _LINUX_LIST_H #define _LINUX_LIST_H struct list_head { struct list_head *next, *prev; }; #define LIST_HEAD_INIT(name) { &(name), &(name) } #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) );}) static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list; list->prev = list; } 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_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 = NULL; entry->prev = NULL; } #define prefetch(x) __builtin_prefetch(x) //注:這里prefetch 是gcc的一個優化,也可以不要 #define list_for_each(pos, head) \ for (pos = (head)->next; prefetch(pos->next), pos != (head); \ pos = pos->next) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) #endif
寫了一個簡單的應用程序:
#include "list.h" #include <stdio.h> #include <string.h> #define MAX_NAME_LEN 32 #define MAX_ID_LEN 10 typedef struct stud { struct list_head list; char name[MAX_NAME_LEN]; char stu_number[MAX_ID_LEN]; }num_n_stu; int main(void) { struct list_head head; num_n_stu stu_1; num_n_stu stu_2; num_n_stu *entry; struct list_head *p; INIT_LIST_HEAD(&head); strcpy(stu_1.name,"lisi"); strcpy(stu_1.stu_number,"10000000"); strcpy(stu_2.name,"zhangsan"); strcpy(stu_2.stu_number,"10000001"); list_add(&stu_1.list,&head); list_add(&stu_2.list,&head); list_del(&stu_2.list); list_for_each(p,&head) { entry=list_entry(p,struct stud,list); printf("name: %s\n",entry->name); printf("stu_number: %s\n",entry->stu_number); } list_del(&stu_1.list); return 0; }
在Linux內核中可以使用這個以類似驅動模塊的形式加載到內核:(這里就不用使用自定義的list.h了)
#include <linux/list.h> #include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("GPL"); #define MAX_NAME_LEN 32 #define MAX_ID_LEN 10 typedef struct stud { struct list_head list; char name[MAX_NAME_LEN]; char stu_number[MAX_ID_LEN]; }num_n_stu; static int my_main(void) { struct list_head head; num_n_stu stu_1; num_n_stu stu_2; num_n_stu *entry; struct list_head *p; INIT_LIST_HEAD(&head); strcpy(stu_1.name,"lisi"); strcpy(stu_1.stu_number,"10000000"); strcpy(stu_2.name,"zhangsan"); strcpy(stu_2.stu_number,"10000001"); list_add(&stu_1.list,&head); list_add(&stu_2.list,&head); list_del(&stu_2.list); list_for_each(p,&head) { entry=list_entry(p,struct stud,list); printk("name: %s\n",entry->name); printk("stu_number: %s\n",entry->stu_number); } list_del(&stu_1.list); return 0; } static void my_exit(void) { printk("my_exit ! \n"); } module_init(my_main); module_exit(my_exit);
