• Linux 内核链表使用举例


    链表数据结构的定义非常简洁:

    struct list_head { 
        struct list_head *next, *prev;
    }; 

    list_head结构包括两个指向list_head结构的指针prev和next。该内核链表具备双链表功能。通常它都组织成双循环链表,这里的list_head没有数据域。在Linux内核链表中,不是在链表结构中包括数据,而是在数据结构中包括链表节点。以下是一个简单的内核模块的样例。包括了对链表进行插入、删除、遍历的一些函数:

    list.c:

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/init.h>
    #include <linux/string.h>
    #include <linux/spinlock.h>
    #include <linux/list.h>
    
    typedef struct list_test_struct {
            int num;
            struct list_head list;
    }test;
    
    struct list_head head_list;
    rwlock_t list_lock = RW_LOCK_UNLOCKED;   //定义读写锁,操作前加锁,操作后解锁
    
    void creat_list(void)
    {
            test *s = NULL;
            int  i = 0;
            for (i = 0; i < 10; i++) 
            {
                    s = (test *)kmalloc(sizeof(test), GFP_ATOMIC);
                    if (!s) return ;
                    s->num = i;
                    write_lock(&list_lock);
                    list_add_tail(&(s->list), &head_list);   //加入节点
                    write_unlock(&list_lock);
            }
    }
    
    void del_data(void)
    {
            test *s;
            struct list_head *p;
    
            write_lock(&list_lock);
            list_for_each(p, &head_list)          //遍历链表
            {
                    s = list_entry(p, test, list);
                    if (s->num == 4) 
                    {
                            list_del(p);          //删除节点
                            write_unlock(&list_lock);
                            return ;
                    }
            }
            write_unlock(&list_lock);
    }
    
    void print_list(void)
    {
            test *s;
            struct list_head *p;
            read_lock(&list_lock);
            list_for_each(p, &head_list) 
            {
                    s = list_entry(p, test, list);
                    printk(KERN_INFO"%d
    ", s->num);
            }
            read_unlock(&list_lock);
    }
    
    int list_test_init(void)
    {
            INIT_LIST_HEAD(&head_list);
            creat_list();
            print_list();
            del_data();
            print_list();
            return 0;
    }
    
    void list_test_exit(void)
    {
    	return;
    }
    
    MODULE_LICENSE("GPL");
    module_init(list_test_init);
    module_exit(list_test_exit);
    
    Makefile:

    obj-m	+= list.o
    
    KERN_DIR = /usr/src/linux-headers-2.6.32-33-generic
    
    all:
    	make -C $(KERN_DIR) M=`pwd` modules 
    
    clean:
    	make -C $(KERN_DIR) M=`pwd` modules clean
    	rm -rf modules.order

    make后生成module,获取超级用户权限后

    insmod list.ko

    然后输入命令:

    cat var/log/messages

    printk信息打印:

    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274551] 0
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274553] 1
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274555] 2
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274555] 3
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274556] 4
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274557] 5
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274558] 6
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274559] 7
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274559] 8
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274560] 9
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274561] 0
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274562] 1
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274563] 2
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274564] 3
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274564] 5
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274565] 6
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274566] 7
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274567] 8
    Jun 20 16:26:01 wuwen-laptop kernel: [ 5490.274568] 9
    第二次输出发现节点4被删除。在这里实现:

           list_for_each(p, &head_list)          //遍历链表
           {
                    s = list_entry(p, test, list);
                    if (s->num == 4) 
                    {
                            list_del(p);          //删除节点
                            write_unlock(&list_lock);
                            return ;
                    }
            }

  • 相关阅读:
    java ,js获取web工程路径
    js 无刷新分页代码
    js 获取时间对象代码
    jquery 文本框失去焦点显示提示信息&&单击置空文本框
    CodeForces
    nth_element() O(n)复杂度求第k+1小元素
    CodeForces
    HDU
    杜教BM
    J
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7068840.html
Copyright © 2020-2023  润新知