IT培训机构|91免费精品视频|专注编程培训|91免费精品|软件开发培训_91免费国产视频_华清远见教育


ARM Linux中鏈表使用實(shí)例

分享到:
           

    1、ARM Linux內(nèi)核鏈表概述

    在ARM Linux中,鏈表是為基本的數(shù)據(jù)結(jié)構(gòu),也是為常用的數(shù)據(jù)結(jié)構(gòu)。在本文中盡管使用2.6內(nèi)核作為講解的基礎(chǔ),但實(shí)際上2.4內(nèi)核中的鏈表結(jié)構(gòu)和2.6并沒有太大區(qū)別。二者不同之處在于2.6擴(kuò)充了兩種鏈表數(shù)據(jù)結(jié)構(gòu):鏈表的讀拷貝更新(rcu)和HASH鏈表(hlist)。這兩種擴(kuò)展都是基于基本的list結(jié)構(gòu)。因此,在此處主要介紹基本鏈表結(jié)構(gòu)。

    鏈表數(shù)據(jù)結(jié)構(gòu)的定義很簡單(<include/linux/list.h>,以下所有代碼除非加以說明,其余均取自該文件):

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

    list_head結(jié)構(gòu)包含兩個(gè)指向list_head結(jié)構(gòu)的指針prev和next,由此可見,內(nèi)核的鏈表具備雙鏈表功能,實(shí)際上,通常它都組織成雙循環(huán)鏈表。

    和之前介紹的雙鏈表結(jié)構(gòu)模型不同,這里的list_head沒有數(shù)據(jù)域。在Linux內(nèi)核鏈表中,不是在鏈表結(jié)構(gòu)中包含數(shù)據(jù),而是在數(shù)據(jù)結(jié)構(gòu)中包含鏈表節(jié)點(diǎn)。由于鏈表數(shù)據(jù)類型差別很大,如果對每一種數(shù)據(jù)項(xiàng)類型都需要定義各自的鏈表結(jié)構(gòu),不利于抽象成為公共的模板。

    在Linux內(nèi)核鏈表中,需要用鏈表組織起來的數(shù)據(jù)通常會包含一個(gè)struct list_head成員,例如在<include/linux/netfilter.h>中定義了一個(gè)nf_sockopt_ops結(jié)構(gòu)來描述netfilter為某一協(xié)議族準(zhǔn)備的getsockopt/setsockopt接口,其中就有一個(gè)(struct list_head list)成員,各個(gè)協(xié)議族的nf_sockopt_ops結(jié)構(gòu)都通過這個(gè)list成員組織在一個(gè)鏈表中,表頭是定義在<net/core/netfilter.c>中的nf_sockopts(struct list_head)。讀者可以看到,Linux的簡捷實(shí)用、不求完美和標(biāo)準(zhǔn)的風(fēng)格在這里體現(xiàn)得相當(dāng)充分。

    2、Linux內(nèi)核鏈表接口

    (1)聲明和初始化

    實(shí)際上Linux只定義了鏈表節(jié)點(diǎn),并沒有專門定義鏈表頭,那么一個(gè)鏈表結(jié)構(gòu)是如何建立起來的呢?這里是使用LIST_HEAD()這個(gè)宏來構(gòu)建的。

    #define LIST_HEAD_INIT(name) { &(name), &(name) }
    #define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)

    這樣,當(dāng)需要用LIST_HEAD(nf_sockopts)聲明一個(gè)名為nf_sockopts的鏈表頭時(shí),它的next、prev指針都初始化為指向自己。這樣就構(gòu)建了一個(gè)空鏈表,因?yàn)長inux用頭指針的next是否指向自己來判斷鏈表是否為空。

    static inline int list_empty(const struct list_head *head)
    { return head->next == head; }

    除了用LIST_HEAD()宏在聲明的時(shí)候創(chuàng)建一個(gè)鏈表以外,Linux還提供了一個(gè)INIT_LIST_HEAD宏用于運(yùn)行時(shí)創(chuàng)建鏈表:

    #define INIT_LIST_HEAD(ptr) do { (ptr)->next = (ptr);
    (ptr)->prev = (ptr); } while (0)

    (2)插入

    對鏈表的插入操作有兩種:在表頭插入和在表尾插入。Linux為此提供了兩個(gè)接口:

    static inline void list_add(struct list_head *new, struct list_head *head);
    static inline void list_add_tail(struct list_head *new, struct list_head *head);

    因?yàn)長inux鏈表是循環(huán)表,且表頭的next、prev分別指向鏈表中的第一個(gè)和末一個(gè)節(jié)點(diǎn),所以,list_add()和list_add_tail()的區(qū)別并不大,實(shí)際上,Linux分別用以下兩個(gè)函數(shù)來實(shí)現(xiàn)接口。

    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_add_tail(struct list_head *new, struct list_head *head)
    {
        __list_add(new, head->prev, head);
    }

    (3)刪除

    Linux中刪除的代碼也是類似的,通過__list_del來實(shí)現(xiàn)list_del接口,讀者可以自行分析以下代碼段:

    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 = LIST_POISON1;
        entry->prev = LIST_POISON2;
    }

    從接口函數(shù)中可以看到,被刪除下來的prev、next指針分別被設(shè)為LIST_POSITION2和LIST_POSITION1兩個(gè)特殊值,這樣設(shè)置是為了保證不在鏈表中的節(jié)點(diǎn)項(xiàng)不可訪問,對LIST_POSITION1和LIST_POSITION2的訪問都將引起頁故障。與之相對應(yīng),list_del_init()函數(shù)將節(jié)點(diǎn)從鏈表中解下來之后,調(diào)用LIST_INIT_HEAD()將節(jié)點(diǎn)置為空鏈狀態(tài)。

   熱點(diǎn)鏈接:

   1、嵌入式linux內(nèi)核數(shù)據(jù)結(jié)構(gòu)之循環(huán)鏈表
   2、嵌入式linux內(nèi)核數(shù)據(jù)結(jié)構(gòu)之雙向鏈表
   3、嵌入式linux內(nèi)核數(shù)據(jù)結(jié)構(gòu)之單向鏈表

更多新聞>> 

主站蜘蛛池模板: 微机继电保护测试仪,单相继电保护测试仪,三相继电保护测试仪,六相继电保护测试仪,介质损耗测试仪,氧化锌避雷器测试仪,无线核相仪-扬州豪泰电力科技有限公司 | 郑州阳光房|封阳台|钢结构【河南郑州如意阳光房门窗有限公司】 | 生活污水处理工程安装承包-江苏富瑞源环境工程有限公司 | 全自动滤水器_射水抽气器_气液两相流疏水器-连云港神美电力辅机有限公司 | 欧氏运动木地板,体育木地板厂家,篮球木地板价格_欧氏体育木地板 欧派板材官网 | 全屋定制板材 专业供应商 | 郑州同林-金属切削液,全合成,半合成,防锈水溶性,微乳,油基长寿乳化切削液生产厂家 | 苏州西服定制,西装定做时尚职业装品牌-尊羿西服定做网 | 首页-上海钢之杰智能建筑集团股份有限公司 | 新乡市矿山起重机制造有限公司| 水阻柜-液阻柜-高压开关柜-高压固态软启动柜-磁控软启动柜-电解粉-无功补偿柜-配电柜-襄阳源创电气 | 银联POS机_银联微信支付宝刷卡POS机_外币POS机_移动POS机办理安装——谷骐科技 | 亚洲一区日韩一区欧美一区a,中文字幕乱妇无码AV在线,欧美日韩免费在线观看,国产精品一区二区三区免费,日韩精品免费一线在线观看,日韩一本在线,国产呦精品一区二区三区下载,国产日韩精品一区二区在线观看,欧美日韩高清一区二区三区,日韩在线免费观看视频,欧美日韩一区在线观看 | 皮革耐折试验机-消字率测试仪-面具全视野测试仪-东莞市誉扬检测仪器有限公司 | 河北高新技术企业认定,沧州商标注册,沧州9001质量管理体系认证,沧州高新技术企业认定,沧州体系认证,沧州商标续展,沧州版权登记,河北国瑞企业管理咨询有限公司 | 长沙广告设计公司|长沙广告制作|湖南户外广告制作|商业美陈就找湖南盛翔文化传媒有限公司老品牌高品质 | 昆明纸箱厂-礼盒定制-包装盒定做-纸箱厂-云南包掌柜包装有限公司 | 射频导纳物位开关|雷达液位计|安全光栅光幕传感器|音叉料位开关|两级跑偏开关|双向拉绳开关|纵向撕裂保护装置-山东卓信机械有限公司 | 英格索兰隔膜泵_ARO气动隔膜泵_英格索兰隔膜泵配件【原厂正品】连续五年无投诉_英格索兰隔膜泵代理-苏州瑞晟茂环保设备有限公司 印刷公司,北京印刷厂,宣传画册手册印刷厂-和智印彩页设计 | 无锡市钧辉机械制造有限公司| 上饶市蚂蚁搬家有限公司,上饶搬家公司,上饶同城搬家,上饶同城搬家电话,上饶搬家哪家好,上饶搬家公司电话 | 内蒙古浩泽环保集团股份公司,内蒙古环保设备,内蒙古污水处理,内蒙古在线监测 | 液体灌装机-酱料灌装机-全自动灌装机-旋盖机-铝箔封口机-贴标机厂家-迈特威自动化设备(天津)有限公司" | 生物质蒸发器_燃气蒸发器_燃气锅炉价格|厂家直销-山东泰锅锅炉设备有限公司 | 上海物业管理_写字楼物业管理_厂房物业管理_上海企福物业管理有限公司 | 石膏砂浆生产线_特种砂浆生产线_轻质抹灰石膏设备-青岛环港重工科技有限公司 | 西门子伺服电机维修_西门子变频器维修_西门子伺服驱动器维修_数控系统维修_PL维修-上海仰光电子 西克制冷官网│制冷机组冷风机冷库设备厂家-西克制冷(无锡)有限公司_西克制冷(无锡)有限公司 | 金相切割机-金相磨抛机-显微/维氏/布氏/洛氏硬度计-自准直仪-金相显微镜-万能材料试验机-清洁度检测仪-淋雨试验机-上海中研精密仪器制造有限公司 | 河北高新技术企业认定,沧州商标注册,沧州9001质量管理体系认证,沧州高新技术企业认定,沧州体系认证,沧州商标续展,沧州版权登记,河北国瑞企业管理咨询有限公司 | 重庆宏工_隧道取芯钻机_公路护栏钻机-车载式钻机_打钻一体机_护栏抢修车_隧道钻机-工程机械 | 室内通风系统,新风系统专卖,建筑通风系统专卖_绿岛风官网 | 危废处理_危废处置_危废处理公司-江苏绿瑞特环境科技股份有限公司 | 西安鸿仁汇智软件公司是高新技术企业,专业为企业及高校提供智慧化管理一站式解决方案 | 生物安全柜检测,GMP设备确认,仪器性能确认,洁净厂房检测,仓储温湿度检测-上海熙迈 | 上海网站建设-上海网站制作-网站设计-上海做网站公司-SEO优化推广-咏熠软件 | 苏州探测器清洗_烟感探头清洗_感烟探测器维修清洗_火灾探测器清洗报价/价格_进口国产消防设备清洗_江苏智淼探测器清洗厂家- | 实验反应釜,高压反应釜,玻璃反应釜,不锈钢反应釜-烟台招远松岭化工设备有限公司 | 久久91精品久久91综合_国产亚洲自拍一区_国产精品第1页_亚洲高清视频一区_91成人午夜在线精品_亚洲国产精品网站在线播放_亚洲国产成人久久综合区_国产精品亚洲专区在线观看_免费视频精品一区二区三区 | 廊坊大地木业有限公司| 全自动码垛机械手,码垛机器人,拆包机,缠绕机,开箱封箱装箱机厂家-山东昊宇自动化设备有限公司 | 数控滑台,机床滑台,十字滑台,直线滑台,三轴滑台,立柱滑台厂家-泊头市北重机械制造有限公司 | 咪咕体育直播,咪咕直播,CCTV5直播,体育直播,高清直播,腾讯体育直播,篮球直播,足球直播 |