5 删除双向链表节点

双向链表提供两种链表节点的删除方法,删除指定节点LOS_ListDelete()、删除并初始化为一个新链表LOS_ListDelInit()


6 获取双向链表节点

双向链表还提供宏定义获取指定链表节点的前驱节点LOS_DL_LIST_LAST,获取指定链表节点的后继节点LOS_DL_LIST_FIRSTOpenHarmony LiteOS-M内核源码分析时,已经了解这2个宏,我们继续看下2个判断的宏,即LOS_DL_LIST_IS_ENDLOS_DL_LIST_IS_ON_QUEUE

6.1 LOS_DL_LIST_IS_END

通过判断两个链表节点是否相等,通常第一个为尾节点,第二个是变化的链表节点,判断是否遍历到尾节点。

源码如下:

#define LOS_DL_LIST_IS_END(list, node) ((list) == (node) ? TRUE : FALSE)

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

6.2 LOS_DL_LIST_IS_ON_QUEUE

用于判断链表节点是否在循环链表中,即前序、后继节点都不为空。

源码如下:

#define LOS_DL_LIST_IS_ON_QUEUE(node) ((node)->pstPrev != NULL && (node)->pstNext != NULL)

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

7 遍历双向循环链表节点

双向循环链表提供两种遍历双向链表的方法,LOS_DL_LIST_FOR_EACHLOS_DL_LIST_FOR_EACH_SAFEOpenHarmony LiteOS-M内核源码分析时,已经分析过这2个宏。


8 获取链表节点所在结构体

通过宏LOS_DL_LIST_ENTRY可以获取成员变量相对于结构体的内存地址偏移量。通过宏LOS_DL_LIST_ENTRY``即可以获取双向链表节点所在的业务结构体的内存地址。OpenHarmony LiteOS-M内核源码分析时,已经分析过这2个宏。我们分析下OpenHarmony LiteOS-A内核中独有的三个宏,即LOS_ListPeekHeadTypeLOS_ListRemoveHeadTypeLOS_ListNextType`。

8.1 LOS_ListPeekHeadType

函数宏中的三个参数分别为:业务结构体类型名称type,作为结构体成员的双向链表成员变量名称element,双向链表头节点指针list。通过调用该宏函数LOS_ListPeekHeadType即可以获取双向链表第一个业务链表节点所在的业务结构体的内存地址。

⑴处表示如果是只有头链表结点的空双向循环链表,则返回NULL。⑵如果链表不为空,调用宏LOS_DL_LIST_ENTRY获取业务结构体的内存地址。该宏相对宏LOS_DL_LIST_ENTRY更安全,如果是空的双向链表,调用后者,返回的内存地址不是业务结构体的地址,会发生踩内存错误。

源码如下:

#define LOS_ListPeekHeadType(list, type, element) ({             \
    type *__t;                                                   \
⑴  if ((list)->pstNext == list) {                               \
        __t = NULL;                                              \
    } else {                                                     \
⑵      __t = LOS_DL_LIST_ENTRY((list)->pstNext, type, element); \
    }                                                            \
    __t;                                                         \
})
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

8.2 LOS_ListRemoveHeadType

函数宏中的三个参数分别为:业务结构体类型名称type,作为结构体成员的双向链表成员变量名称element,双向链表头节点指针list。通过调用该宏函数LOS_ListRemoveHeadType即可以获取双向链表第一个业务链表节点所在的业务结构体的内存地址,并把第一个业务链表节点从双向链表中删除。

⑴处表示如果是只有头链表结点的空双向循环链表,则返回NULL。⑵如果链表不为空,获取业务结构体的内存地址,然后调用LOS_ListDelete删除链表节点。

源码如下:

#define LOS_ListRemoveHeadType(list, type, element) ({           \
    type *__t;                                                   \
    if ((list)->pstNext == list) {                               \
⑴      __t = NULL;                                              \
    } else {                                                     \
⑵      __t = LOS_DL_LIST_ENTRY((list)->pstNext, type, element); \
        LOS_ListDelete((list)->pstNext);                         \
    }                                                            \
    __t;                                                         \
})

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

8.3 LOS_ListNextType

函数宏中的四个参数分别为:业务结构体类型名称type,作为结构体成员的双向链表成员变量名称element,双向链表头节点指针list,双向链表中的一个节点item。通过调用该宏函数LOS_ListNextType即可以获取双向链表指定链表节点的下一个节点所在的业务结构体的内存地址。

⑴处表示如果指定链表节点的下一个节点是头结点,则返回NULL。否则执行⑵,获取指定链表节点的下一个节点所在的业务结构体的内存地址。

源码如下:

#define LOS_ListNextType(list, item, type, element) ({           \
    type *__t;                                                   \
    if ((item)->pstNext == list) {                               \
⑴      __t = NULL;                                              \
    } else {                                                     \
⑵      __t = LOS_DL_LIST_ENTRY((item)->pstNext, type, element); \
    }                                                            \
    __t;                                                         \
})

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

9 遍历包含双向链表的结构体

双向链表提供三个宏定义来遍历包含双向链表成员的结构体,LOS_DL_LIST_FOR_EACH_ENTRYLOS_DL_LIST_FOR_EACH_ENTRY_SAFELOS_DL_LIST_FOR_EACH_ENTRY_HOOKOpenHarmony LiteOS-M内核源码分析时,已经分析过这3个宏。


小结

掌握鸿蒙轻内核的双向循环链表LOS_DL_LIST这一重要的数据结构,会给进一步学习、分析鸿蒙轻内核源代码打下了基础,让后续的学习更加容易。

如果大家想更加深入的学习 OpenHarmony 开发的内容,不妨可以参考以下相关学习文档进行学习,助你快速提升自己:

OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

系统架构分析:https://qr18.cn/CgxrRy

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

在这里插入图片描述

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

data-report-view="{"mod":"1585297308_001","spm":"1001.2101.3001.6548","dest":"https://blog.csdn.net/maniuT/article/details/139598879","extend1":"pc","ab":"new"}">> id="blogExtensionBox" style="width:400px;margin:auto;margin-top:12px" class="blog-extension-box"> class="blog_extension blog_extension_type2" id="blog_extension"> class="extension_official" data-report-click="{"spm":"1001.2101.3001.6471"}" data-report-view="{"spm":"1001.2101.3001.6471"}"> class="blog_extension_card_left"> class="blog_extension_card_cont"> 鸿蒙开发学习资料领取!!! class="blog_extension_card_cont_r"> 微信名片
注:本文转载自blog.csdn.net的沧海一笑-dj的文章"https://blog.csdn.net/dengjin20104042056/article/details/98382001"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!