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);
  • 相关阅读:
    tomcat 含中文文件不能下载问题
    【转】解读Tomcat服务器server.xml文件
    java 删除文件和文件夹
    获取tomcat安装地址
    《Zookeeper中间件》Zookeeper整合SpringBoot
    《Zookeeper中间件》Zookeeper源码环境搭建
    《Java基础知识》Java 阻塞队列
    《Zookeeper中间件》Zookeeper安装(linux)
    《RabbitMQ 消息中间件》Rabbit集群架构
    《RabbitMQ 消息中间件》RabbitMQ的应用场景
  • 原文地址:https://www.cnblogs.com/FarmPick/p/5420316.html
Copyright © 2011-2022 走看看