• linux内核双向链表list的使用


    list.h文件

    #ifndef __TONGYISHU_LIST_H
    #define __TONGYISHU_LIST_H
    
    #undef offsetof
    #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    
    /**
     * container_of - cast a member of a structure out to the containing structure
     * @ptr:        the pointer to the member.
     * @type:       the type of the container struct this is embedded in.
     * @member:     the name of the member within the struct.
     *
     */
    #undef container_of
    #define container_of(ptr, type, member) ({                      
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    
        (type *)( (char *)__mptr - offsetof(type,member) );})
    
    
    struct list_head {
        struct list_head *next, *prev;
    };
    
    #undef LIST_HEAD_INIT
    #define LIST_HEAD_INIT(name) 
        do { 
            (name).prev = &(name); 
            (name).next = &(name); 
        } while (0)
    
    /**
     * list_entry - get the struct for this entry
     * @ptr:    the &struct list_head pointer.
     * @type:    the type of the struct this is embedded in.
     * @member:    the name of the list_struct within the struct.
     */
    #undef list_entry
    #define list_entry(ptr, type, member) 
        container_of(ptr, type, member)
    
    /**
     * list_for_each_entry    -    iterate over list of given type
     * @pos:    the type * to use as a loop cursor.
     * @head:    the head for your list.
     * @member:    the name of the list_struct within the struct.
     */
    #undef list_for_each_entry
    #define list_for_each_entry(pos, head, member)                
        for (pos = list_entry((head)->next, typeof(*pos), member);    
             &pos->member != (head);     
             pos = list_entry(pos->member.next, typeof(*pos), member))
    
    /**
     * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
     * @pos:    the type * to use as a loop cursor.
     * @n:        another type * to use as temporary storage
     * @head:    the head for your list.
     * @member:    the name of the list_struct within the struct.
     */
    #undef list_for_each_entry_safe
    #define list_for_each_entry_safe(pos, n, head, member)            
        for (pos = list_entry((head)->next, typeof(*pos), member),    
            n = list_entry(pos->member.next, typeof(*pos), member);    
             &pos->member != (head);                    
             pos = n, n = list_entry(n->member.next, typeof(*n), member))
    
    /**
     * list_empty - tests whether a list is empty
     * @head: the list to test.
     */
    static inline int list_empty(const struct list_head *head)
    {
        return head->next == head;
    }
    
    /*
     * Insert a new entry between two known consecutive entries.
     *
     * This is only for internal list manipulation where we know
     * the prev/next entries already!
     */
    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;
    }
    
    /**
     * list_add_tail - add a new entry
     * @new: new entry to be added
     * @head: list head to add it before
     *
     * Insert a new entry before the specified head.
     * This is useful for implementing queues.
     */
    static inline void list_add_tail(struct list_head *_new, struct list_head *head)
    {
        __list_add(_new, head->prev, head);
    }
    
    /*
     * Delete a list entry by making the prev/next entries
     * point to each other.
     *
     * This is only for internal list manipulation where we know
     * the prev/next entries already!
     */
    static inline void __list_del(struct list_head *prev, struct list_head *next)
    {
        next->prev = prev;
        prev->next = next;
    }
    
    #undef LIST_POISON1
    #define LIST_POISON1  ((void *) 0x00100100)
    #undef LIST_POISON2
    #define LIST_POISON2  ((void *) 0x00200200)
    
    /**
     * list_del - deletes entry from list.
     * @entry: the element to delete from the list.
     * Note: list_empty() on entry does not return true after this, the entry is
     * in an undefined state.
     */
    static inline void list_del(struct list_head *entry)
    {
        __list_del(entry->prev, entry->next);
        entry->next = (struct list_head*)LIST_POISON1;
        entry->prev = (struct list_head*)LIST_POISON2;
    }
    #endif

    main.c文件

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include "list.h"
    
    struct Staff {
        struct list_head list;
        char id[10];
        char name[20];
    };
    
    int main()
    {
        struct Staff staff_head = { 0 };
        struct Staff *pos = NULL, *next = NULL;
        LIST_HEAD_INIT(staff_head.list);
    
        /* list add */
        printf("%s", ">>>>>>> list add start.
    ");
        for (int i = 0; i < 3; i++) {
            pos = (struct Staff*)malloc(sizeof(struct Staff));
            sprintf(pos->id, "%s%d", "t0051260", i);
            sprintf(pos->name, "%s%d", "tongyishu-", i);
            list_add_tail(&pos->list, &staff_head.list);
            printf("> add list node : 
    ");
            printf("  id   : %s
    ", pos->id);
            printf("  name : %s
    ", pos->name);
        }
        printf("%s", ">>>>>>> list add end.
    ");
    
        /* list for each */
        printf("%s", ">>>>>>> list for each start.
    ");
        list_for_each_entry(pos, &staff_head.list, list)
        {
            printf("  id : %s
    ", pos->id);
            printf("  name : %s
    ", pos->name);
        }
        printf("%s", ">>>>>>> list for each end.
    ");
    
        /* delete node("t00512601", "tongyishu-1") */
        printf("%s", ">>>>>>> delete node start.
    ");
        list_for_each_entry_safe(pos, next, &staff_head.list, list)
        {
            if (strcmp("t00512601", pos->id) == 0) {
                list_del(&pos->list);
                printf("> delete list node : 
    ");
                printf("  id   : %s
    ", pos->id);
                printf("  name : %s
    ", pos->name);
                free(pos);
            }
        }
        printf("%s", ">>>>>>> delete node end.
    ");
    
        /* list for each again */
        printf("%s", ">>>>>>> list for each after delete node start.
    ");
        list_for_each_entry(pos, &staff_head.list, list)
        {
            printf("  id   : %s
    ", pos->id);
            printf("  name : %s
    ", pos->name);
        }
        printf("%s", ">>>>>>> list for each after delete node end.
    ");
    
    
        /* release resource */
        printf("%s", ">>>>>>> release resource start.
    ");
        list_for_each_entry_safe(pos, next, &staff_head.list, list)
        {
            list_del(&pos->list);
            free(pos);
        }
        printf("%s", ">>>>>>> release resource end.
    ");
    
        return 0;
    }

    输出结果:

    >>>>>>> list add start.
    > add list node :
      id   : t00512600
      name : tongyishu-0
    > add list node :
      id   : t00512601
      name : tongyishu-1
    > add list node :
      id   : t00512602
      name : tongyishu-2
    >>>>>>> list add end.
    >>>>>>> list for each start.
      id : t00512600
      name : tongyishu-0
      id : t00512601
      name : tongyishu-1
      id : t00512602
      name : tongyishu-2
    >>>>>>> list for each end.
    >>>>>>> delete node start.
    > delete list node :
      id   : t00512601
      name : tongyishu-1
    >>>>>>> delete node end.
    >>>>>>> list for each after delete node start.
      id   : t00512600
      name : tongyishu-0
      id   : t00512602
      name : tongyishu-2
    >>>>>>> list for each after delete node end.
    >>>>>>> release resource start.
    >>>>>>> release resource end.
  • 相关阅读:
    《数据结构》2.2顺序表(sequence list)
    《算法竞赛入门经典》6.3.1二叉树-小球下落
    java_时间戳与Date_相互转化
    java事物
    Mysql如何向存在外键的数据表中插入数据
    git基本配置
    mysql时间属性之时间戳和datetime之间的转换
    【转】变量命名(简短且无歧义)
    【转】mybatis实战教程(mybatis in action),mybatis入门到精通
    [转]DAO层,Service层,Controller层、View层
  • 原文地址:https://www.cnblogs.com/tongyishu/p/13138372.html
Copyright © 2020-2023  润新知