zoukankan      html  css  js  c++  java
  • 内核链表操作函数/宏

    之前说过Linux内核中建立了一套内核链表体系,包括在内核中链表的定义和使用方法。由于内核中定义的对链表的操作方法太多了,限于时间和能力的问题,我将记录在学习过程

    中所用到的操作方法。

    内核中源文件位置:includelinuxlist.h

     

    1、list_entry宏

    (1)原型:  #define list_entry(ptr, type, member)   container_of(ptr, type, member)

    (2)作用:从上面可以看出来,list_entry宏其实就是container_of宏,这个宏之前说过,是内核中一个很重要的宏。可以通过结构体中的某一个变量的指针来获取

                 整个结构体变量的指针;ptr就是这个结构体中某个变量的指针,type就是这个结构体的类型,member就是ptr指针对应的变量的变量名。

    (3)使用例子:

    1 struct A{
    2     int a;
    3     int b;
    4     int c;
    5 };
    6 struct A a = {0};
    7 struct A *ptr = list_entry(&a.a, struct A, a);  // 或者是 container_of(&a.a, struct A, a)

    2、list_for_each_entry宏

    (1)原型:

    #define list_for_each_entry(pos, head, member)
    for (pos = list_entry((head)->next, typeof(*pos), member);
    prefetch(pos->member.next), &pos->member != (head);
    pos = list_entry(pos->member.next, typeof(*pos), member))

    (2)作用:这个宏就是内核中提供的遍历链表的宏,内核链表并不是单独使用,而是被其他的结构体包含,所有的同一类型的结构体变量通过内置的内核链表连接起来。

        我们可以通过list_for_each_entry宏来遍历所有的连接在一起的结构体变量。 pos就是内置了内核链表的结构体变量的指针,head就是结构体内内置的内核链表

        的链表头指针,member就是结构体内内置的内核链表的变量名。内部是通过for循环来实现的,

        list_entry((head)->next, typeof(*pos), member)  其实就是获取内核链表头对应的结构体变量的指针,就是for循环的初始条件

        prefetch(pos->member.next), &pos->member != (head)  就是for循环需要满足的条件

        list_entry(pos->member.next, typeof(*pos), member)  返回下一个内核链表对应的结构体变量指针,就是for循环变量的跟新

    (3)使用例子:

     1  struct list {
     2  2    int a;
     3  3    struct list_head head;
     4  4 };
     5  5 
     6  6 struct list *pList = NULL;
     7  7 struct list list1 = {0};
     8  8 struct list list2 = {0};
     9  9 struct list list3 = {0};
    10 10 
    11 11 INIT_LIST_HEAD(&list1.head);   // 初始化内置的内核链表,使得前向和后向指针都指向本身
    12 12 INIT_LIST_HEAD(&list2.head);
    13 13 INIT_LIST_HEAD(&list3.head);
    14 14 
    15 15 list_add_tail(&list2.head, &list1.head);  // 将list1变量中的内核链表作为链表头,将其他两个添加到list1.head后面
    16 16 list_add_tail(&list3.head, &list1.head);
    17 17 
    18 18 list_for_each_entry(pList, &list1.head, head) // 遍历
    19 19 {
    20 20     ....................   //   操作
    21 21 }    

    未完待续.........................................

     

  • 相关阅读:
    用于表示socket的结构体
    Parcelable与Serializable接口的用法和区别
    java类初始化顺序
    孙卫琴java面向对象编程学习笔记
    linux档案权限
    js弹出模态与非模态页面
    ubuntu开启默认的root用户
    java开发实战学习笔记1
    JQuery ajax回调函数
    hadoop命令
  • 原文地址:https://www.cnblogs.com/deng-tao/p/6089429.html
Copyright © 2011-2022 走看看