zoukankan      html  css  js  c++  java
  • [转载]Linux内核list_head学习(二)

    前一篇文章讨论了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
    ",entry->name);
            printf("stu_number: %s
    ",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
    ",entry->name);
    
            printk("stu_number: %s
    ",entry->stu_number);
    
        }
        
        list_del(&stu_1.list);
        
        return 0;
    
    }
    
    static void my_exit(void)
    {
        printk("my_exit ! 
    ");
    }
    
    
    module_init(my_main);
    module_exit(my_exit);
  • 相关阅读:
    Linux 学习 step by step (1)
    ubuntu server nginx 安装与配置
    ubuntu server samba服务器配置
    iOS app集成支付宝支付流程及后台php订单签名处理
    mac 连接windows 共享内容
    linux 文件查找,which,whereis,locate,find
    ubuntu server vsftpd 虚拟用户及目录
    ubuntu server 安装 mantis bug tracker 中文配置
    ubuntu server vsftpd 匿名用户上传下载及目录设置
    linux 用户管理,用户权限管理,用户组管理
  • 原文地址:https://www.cnblogs.com/FarmPick/p/5420316.html
Copyright © 2011-2022 走看看