• 例说Linux内核链表(三)


    经常使用的linux内核双向链表API介绍

    linux link list结构图例如以下:



    内核双向链表的在linux内核中的位置:/include/linux/list.h

    使用双向链表的过程,主要过程包括创建包括struct link_head结构的结构体(item),建立链表头。向链表中加入item(自己定义数据结构。双向链表数据单元)。删除链表节点。遍历链表,判空等。

    1、建立自己定义链表数据结构

    1. struct kool_list{  
    2.     int to;  
    3.     struct list_head list;  //包括链表头
    4.     int from;  
    5.     };//自己定义欲链接的数据额结构。并包括双向链表结构  
    2、建立链表头

    1.     struct kool_list mylist;  
    2.     INIT_LIST_HEAD(&mylist.list);//初始化一个链表表头  
    3.   
    或者

    static LIST_HEAD(adc_host_head);//初始化一个链表头adc_host_head

    另外一种创建链表头和第一种的差别在于,另外一种在编译的时候才会被初始化。

    另一点就是链表头是独立的还是位于自己定义链表数据结构中的。就好比在《例说Linux内核链表(二)》中给出的链表结构图和本文给出的结构图的差别。

    3、向链表加入item

    list_add(struct list_head *new, struct list_head *head);

    比如:

    1.  struct kool_list *tmp;  

    2.  tmp= (struct kool_list *)malloc(sizeof(struct kool_list));  
    3.           
    4.  printf("enter to and from:");  
    5.  scanf("%d %d", &tmp->to, &tmp->from);  //初始化数据结构
    6.         /* add the new item 'tmp' to the list of items in mylist */  
    7.  list_add(&(tmp->list), &(mylist.list));//项链表中加入新的元素节点,tmp中的list  

    list_add_tail(struct list_head *new, struct list_head *head);

    在链表的尾部加入一个item,和list_add的差别在于,list_add把新的item加到了链表头的后面,list_add_tail把item加到了链表头的前面。

    4、遍历链表

    list_for_each_entry(type *cursor, struct list_head *list, member)

    这并非一个函数。它是一个for循环,依次列出要遍历的链表。三个元素代表的意义:type *cursor代表item的指针,struct list_head *list是链表头,member是item中包括的list_head数据项。

    通过这三个数据能够定位到链表的每个数据元素。当中定位原理就是结构体偏移。

    比如:

    1.  list_for_each_entry(tmp, &mylist.list, list)  
    2.          printf("to= %d from= %d ", tmp->to, tmp->from);  

    这个宏能够分为两步,第一步是遍历链表,pos依次指向链表中每一个item的struct list_head 结构,第二步是获取pos指向的struct list_head所在的item。

    这里是tmp 。

    list_for_each(pos, &mylist.list){//遍历链表,pos依次指向链表的元素

    tmp= list_entry(pos, struct kool_list, list);//获得包括pos节点的数据结构指针    

    5、删除

    删除链表中的某节点,首先要使用安全遍历,然后再删除。

    比如:

      

    1. list_for_each_safe(pos, q, &mylist.list){  
    2.          tmp= list_entry(pos, struct kool_list, list);  
    3.          printf("freeing item to= %d from= %d ", tmp->to, tmp->from);  
    4.          list_del(pos);  

    6、链表空

    int list_empty(struct list_head *head);

    Returns a nonzero value if the given list is empty.


    參考站点:http://www.makelinux.net/ldd3/chp-11-sect-5 

  • 相关阅读:
    xml学习篇(二) ----JSON 和XML对比
    xml学习篇(一)
    在Tomcat下部署web项目
    三枪客
    在Eclipse中使用JUnit4进行单元测试(初级篇)
    在Eclipse中使用JUnit4进行单元测试(高级篇)
    在Eclipse中使用JUnit4进行单元测试(中级篇)
    hibernate学习之Hibernate API
    Hibernate学习之对象持久化
    MySQL【七】单表查询
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6953524.html
Copyright © 2020-2023  润新知