我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Linux内核中的hash与bucket怎么理解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Linux内核中的hash与bucket怎么理解

本文小编为大家详细介绍“Linux内核中的hash与bucket怎么理解”,内容详细,步骤清晰,细节处理妥当,希望这篇“Linux内核中的hash与bucket怎么理解”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

哈希表(Hashtable)又称为“散列”,Hashtable是会根据索引键的哈希程序代码组织成的索引键(Key)和值(Value)配对的集合。Hashtable 对象是由包含集合中元素的哈希桶(Bucket)所组成的。而Bucket是Hashtable内元素的虚拟子群组,可以让大部分集合中的搜寻和获取工作更容易、更快速。

Linux内核中的hash与bucket怎么理解

哈希函数(Hash Function)为根据索引键来返回数值哈希程序代码的算法。索引键(Key)是被存储对象的某些属性值(Value)。当对象加入至 Hashtable时,它存储在与对象哈希程序代码相符的哈希程序代码相关的Bucket中。当在Hashtable内搜寻值时,哈希程序代码会为该值产生,并且会搜寻与该哈希程序代码相关的Bucket。例如,student和teacher会放在不同的Bucket中,而dog和god会放在相同的 Bucket中。所以当索引键是唯一从Hashtable获取元素的性能时表现会较好。Hash的四大优点如下所示。

事先不需要排序。

搜寻速度与数据多少无关。

数字签名的密码技术保密性(Security)高。

可做数据压缩(Data Compression),以节省空间。

Linux内核里的哈希表应用非常广泛,PHP内核里大部分语言特性也是基于哈希表实现的。为什么哈希表能这么神通广大?哈希表能够实现高效的数据存储和查找,而存储和查找是编程中应用最广泛的两个操作。

Linux内核里的哈希表

读过Linux内核源码的人可能都会发现,其中并没有太多复杂的数据结构,作为基础数据结构的双向链表(list)和基于list实现的hash表占据了绝大部分数据结构。内核为什么会大量使用这两种数据结构呢?首先,这两种数据结构都十分简单,简单包括理解起来简单和使用起来简单两方面内容。这也意味着代码的可读性和可维护性都比其他复杂的数据结构要好,出现bug的风险也较低。从哲学上来讲,这也符合K.I.S.S.条款。

其次,内核是一个比较讲究性能的软件,为了程序设计和维护的简单性而失掉性能,这究竟是不是算得不偿失呢?我们是不是应该将天平更加偏向于性能?已经记不起是在哪里听说过,很多商业的路由软件都是基于二叉树的数据结构来存储路由项,以求得其路由查找的时间复杂度为log(n),并且他批评Linux的路由项组织为hash表,致使性能不佳,不适合商业。确实有一定道理,可仔细分析,hash表的性能真的比二叉树差么?二叉树的插入和删除某一项的时间复杂度都为log(n);hash表插入和删除的时间复杂度最好为O(1),最差为O(n),如果选取的表项(m)足够多,且hash函数足够好的话,其时间复杂度为O(n/m)(当m n / log(n)的时候,hash表的平均表现就比二叉树要好;且当m>=n时,其时间复杂度趋近于O(1)。m的值可以做成可调整的,这也正显示了内核的可定制性。不过,不要盲目乐观,这一切都是以一个足够好的hash函数为前期的。

hash函数的优劣

如何判定一个hash函数的好坏呢?hash的中文意思是“散列”,可解释为:分散排列。一个好的hash函数应该做到对所有元素平均分散排列,尽量避免或者降低他们之间的冲突(Collision)。有必要再次提醒大家的是,hash函数的选择必须慎重,如果不幸所有的元素之间都产生了冲突,那么hash表将退化为链表,其性能会大打折扣,时间复杂度迅速降为O(n),绝对不要存在任何侥幸心理,因为那是相当危险的。历史上就出现过利用Linux内核hash函数的漏洞,成功构造出大量使hash表发生碰撞的元素,导致系统被DoS,所以目前内核的大部分hash函数都有一个随机数作为参数进行掺杂,以使其最后的值不能或者是不易被预测。这又对 hash函数提出了第二点安全方面的要求:hash函数最好是单向的,并且要用随机数进行掺杂。提到单向,你也许会想到单向散列函数md4和md5,很不幸地告诉你,他们是不适合的,因为hash函数需要有相当好的性能。Linux内核里面用的jhash是一个久经考验,并被实践证明经得起考验的hash函数,可以CPMS(Copy Paste Modify Save)之。Jhash的作者Bob Jenkins在其网站上还公布了诸如针对能预知的数据进行hash的hash函数–完美(perfect)hash函数等一系列其他hash函数。bucket的英文解释:Hash table lookup operations are often O(n/m) (where n is the number of objects in the table and m is the number of buckets), which is close to O(1), especially when the hash function has spread the hashed objects evenly through the hash table, and there are more hash buckets than objects to be stored.

可以这样理解:

一个HASH的结果所对应的地址可存放两个BUCKET。可解决HASH冲突。

要存数据时,第一次HASH到这里,在第一个BUCKET存放一个数据。

要存数据时,当第二次因某些原因HASH到这里时,在第二个BUCKET存放另一个数据。

一个由5个buckets组成的哈希表,里面有7个元素:

Linux内核中的hash与bucket怎么理解

linux的hash函数hash_long等,用了golden ratio来计算。因为桶(bits)的数量需要由hash函数和对冲突的期望来决定,那么对于hash_long这样的hash函数,我们怎么确定桶的数量呢?一般情况下都是自己根据数据特性来考虑使用的 hash 算法,不是千篇一律咬死一个不放,比如存放 IP 地址的 hash table,用一个 65536 的桶就很好,把 IP 的后 16bit 作为 key。这种方法绝对比 hash_long、jhash 等函数的碰撞率低。其实就是这个界和性能的折中。我可以取我问题空间的最大值。这样肯定能保证键值分散。但是这样会浪费很多空间。然而取得太小,又影响查找效率。感觉还是要在试验中进行测试。而且hash比其他搜索的数据结构灵活的地方就是它的可定制性。可以根据具体情况调整,以达到最优的效果。

读到这里,这篇“Linux内核中的hash与bucket怎么理解”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Linux内核中的hash与bucket怎么理解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Linux内核中的hash与bucket怎么理解

本文小编为大家详细介绍“Linux内核中的hash与bucket怎么理解”,内容详细,步骤清晰,细节处理妥当,希望这篇“Linux内核中的hash与bucket怎么理解”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧
2023-06-27

Linux内核怎么处理中断

这篇文章主要为大家展示了“Linux内核怎么处理中断”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Linux内核怎么处理中断”这篇文章吧。中断是现代 CPU 工作方式中重要的部分。例如:当你每次
2023-06-15

怎么理解Linux内核中的循环链表结构

本篇文章给大家分享的是有关怎么理解Linux内核中的循环链表结构,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。注:文章中引用的代码来源于LXR,所分析的内核版本是v2.6.31
2023-06-17

Linux中的内核怎么升级

这篇文章给大家分享的是有关Linux中的内核怎么升级的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。如果Linux内核过会出现一些问题,比如:网卡不能使用,亮度不能调节,触摸板不能识别,蓝牙不能使用等等,这些关系都
2023-06-28

如何理解linux内核的软中断的情况

这篇文章主要讲解了“如何理解linux内核的软中断的情况”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何理解linux内核的软中断的情况”吧!软中断介绍把可以延迟的处理从硬中断处理程序独立
2023-06-13

Linux内核中的设计模式之全面理解与示例代码

本文介绍了Linux内核中的设计模式,包括单例、工厂、观察者、适配器、策略、状态、代理、装饰器、桥接和组合模式。这些模式用于提高内核的可复用性、可维护性和可扩展性。文章通过数据结构的示例展示了这些模式的应用,有助于理解其原理并在实际开发中使用它们。
Linux内核中的设计模式之全面理解与示例代码
2024-04-02

Linux内核进程上下文切换怎么理解

这篇文章主要讲解了“Linux内核进程上下文切换怎么理解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux内核进程上下文切换怎么理解”吧!1.进程上下文的概念进程上下文是进程执行活动全
2023-06-15

Linux内核中的数据双链表如何理解

这篇文章给大家介绍Linux内核中的数据双链表如何理解,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Linux 内核中自己实现了双向链表,可以在 include/linux/list.h 找到定义。我们将会首先从双向链
2023-06-28

Linux内核处理中断的过程是怎样的

Linux内核处理中断的过程是怎样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。中断是现代 CPU 工作方式中重要的部分。例如:当你每次在键盘上按下一个按键后,CPU 会
2023-06-28

怎么在Ubuntu系统中删除无用的Linux内核

怎么在Ubuntu系统中删除无用的Linux内核?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。查找无用的镜像首先可查看当前用的内核是哪个,可通过命令:uname -a 来获得信
2023-06-07

怎么增强Linux内核中的访问控制安全

这篇文章主要为大家展示了“怎么增强Linux内核中的访问控制安全”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“怎么增强Linux内核中的访问控制安全”这篇文章吧。Linux中常见的拦截过滤用户态
2023-06-16

nginx http内核模块提供的变量怎么理解

本篇内容主要讲解“nginx http内核模块提供的变量怎么理解”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“nginx http内核模块提供的变量怎么理解”吧!ngx_http_core_mo
2023-06-04

怎么理解Linux的硬链接与软链接

这篇“怎么理解Linux的硬链接与软链接”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么理解Linux的硬链接与软链接”文
2023-06-16

Linux内存管理中的slab缓存怎么实现

本文小编为大家详细介绍“Linux内存管理中的slab缓存怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Linux内存管理中的slab缓存怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Linux
2023-06-16

Linux下怎么处理文本文件内容中的^M

这篇文章主要介绍了Linux下怎么处理文本文件内容中的^M,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Windows上写好的文件,在Linux或者Unix下打开,每一行都会
2023-06-13

编程热搜

目录