前言:

最近在啃《 Linux内核设计与实现》,看到第四章CFS时候,读了几遍没太理清这一小节到思路,看到40页这么一句话:“如果这里所讨论的定时器节拍对你来说很陌生,快先去看看第十一章再说。因为这点正是引入CFS的唯一原因”。

于是就先读了十一章:定时器和时间管理,其中提到了linux使用unsigned long jiffies,一个无符号的long记录节拍的数量,如果时钟频率是1000hz,32位的系统上。这个值47.9天就会溢出。如果溢出之前设定了定时器,溢出以后jiffies作为无符号数的值会小于超时时间的值,如果使用current > timeout 就会导致错误的判断。

但是,操作系统提供了宏time_after(current,timeout)可以避免这个问题。看到这个宏的定义,刚开始没有立刻看懂,上网查了一些解析也说的不是很简洁。自己想明白以后,觉得挺有意思,就打算记录一下。希望如果有人在上网查这个的时候,有机会查到我这种思路,看下是不是比较容易理解。

转载:

time_after防止回绕原理

正文:

首先看下这个宏的定义:

#define time_after(current,timeout) ((long)(timeout) - (long)(current)< 0)

WTF?只是把无符号输转化成有符号数就能解决这个问题吗?这是什么原理。。。

下面用我觉得比较简单的思路分析一下这个问题。

首先我们用4位的数字来举例比较简单。

问题是这样发生的:假设当前的时间是13(1101),设定一个节拍以后超时,所以超时时间就是14(1110).然后,过了3个节拍以后,当前时间变成了current = 13 + 3 = 1101 + 0011 = 10000 = 0000 = 0,这个时候虽然超时了,但是(current =0) < (timout=14),如果代码使用if(current > timeout)来判断是否超时就会判断错误。

那么如果把这两个数强制转化成有符号数,是不是就能正确判断了呢?

计算机使用补码存储数字,负数原码转补码是+1以后取反,所以timeout = 1110 转成负数源码就是-1再取反就是(1101取反)1010 也就是-2,current是0,这个时候current = 0 > timeout= -2 是成立的。

但是我的疑问是,这只能保证回绕的时候,timeout - current < 0,那不回绕呢?而且这只测试了回绕的一种情况,不能证明所有的回绕都满足timeout - current < 0吧,怎么证明这个一定成立呢?

time_after防止回绕原理 这个帖子给了我思路,但是感觉他说的还是不够简洁。帖子里说的内容其实可以用一个坐标系图简单的表达出来。其中x轴是无符号数的取值,y轴是对应的有符号数的取值。首先我们在excel中列出4位数的xy所有取值,然后生成曲线图,就很明白了:

current 与 timout 的取值总共分以下4中情况:

1. current 和 timout 都在正数单调递增的部分:

这种情况下 很明显 timeout - current < 0。

2. current 和 timout 都在负数单调递增的部分:

这种情况下同情况1。

3. current 为负数 和 timout 为正数:

这种情况下 timeout - current= 正数-负数 ,应该是一个正数啊,怎么会小于0呢?

问题是最终结果的取值相当于两个点y轴绝对值相加,如果两个点x坐标距离小于8,那么这两个点y的绝对值之和一定大于8,而大于8的无符号数转化成有符号数是一个负数。所以timeout - current <0

4. urrent 为正数 和 timout 为负数:

这种情况下 同情况3,不再赘述。

假设在32位系统使用32位来保存jiffies,1000hz的处理器,想要让两个点的距离超过0xffff,相当于设置一个20多天以后超时的定时任务。这种情况下timeout - current <0才不成立,而内核肯定不会使用这么长的超时时间,所以可以认为timeout - current <0在所有情况下都是成立的。

这样就很清晰的把这个原理表达清楚了。

总结:

第十一章总算是看完了,后边回到第四章在好好理解一下,希望能有新的收获吧~~

最后,让我们保持独立思考,不卑不亢。长成自己想要的样子! (引用自 我非常喜欢的B站up主 ”独立菌儿“->猛戳链接<-的口头禅)

socket read time out解决方法_time_after方法对jiffies回绕问题的解决相关推荐

  1. python tornado websocket_Python Tornado实现WEB服务器Socket服务器共存并实现交互的方法...

    1.背景 最近有个项目,需要搭建一个socket服务器,一个web服务器,然后实现两个服务器之间的通讯交互.刚开始的方案是用Python中socket模块实现一个多线程的socket服务器,然后用Fl ...

  2. 解决overfitting的方法

    解决overfitting的方法 Dropout, regularization, batch normalizatin. 但是要注意dropout只在训练的时候用,让一部分神经元随机失活. Batc ...

  3. Centos6 升级glibc-2.17,解决Requires: libc.so.6(GLIBC_2.14)(64bit)错误解决方法

    Centos6 升级glibc-2.17,解决Requires: libc.so.6(GLIBC_2.14)(64bit)错误解决方法 参考文章: (1)Centos6 升级glibc-2.17,解决 ...

  4. C# 加载图片image --(C#)Image.FromFile 方法会锁住文件的原因及可能的解决方法

    C# 加载图片image --(C#)Image.FromFile 方法会锁住文件的原因及可能的解决方法 参考文章: (1)C# 加载图片image --(C#)Image.FromFile 方法会锁 ...

  5. html宽度自适应怎么调整li超出隐藏,HTML篇之CSS样式——div ul li 嵌套后解决高度自适应方法...

    方法一: div 自适应宽度 很简单 ,你应该设置div的display:inline-block 然后不要设置宽度就行了 方法二: div ul li 嵌套后解决高度自适应办法: html代码如下 ...

  6. 帝国cms后台上传大视频上传m3u8批量上传一次多个的解决思路和方法

    今天我们要解决的问题是,大视频文件上传以及切片m3u8文件的上传.上面一节内容,我们已经整体描述了视频类网站的解决思路和方法 .这节我们将分块来讲.假设的前提条件是,我们本地准备了一些视频原始素材,比 ...

  7. dnf服务器未响应win7,win7dnf未响应怎么解决|分享win7系统dnf总是未响应的解决方法...

    收到反馈win7dnf未响应怎么解决|分享win7系统dnf总是未响应的解决方法,相信dnf的忠实用户们一定会遇到dnf未响应的问题吧,有些小伙伴们还是经常性的会遇到这种问题,就来求助小编给出解决方法 ...

  8. java socket建立长连接_Java Web项目中使用Socket通信多线程、长连接的方法

    很多时候在javaweb项目中我们需要用到Socket通信来实现功能,在web中使用Socket我们需要建立一个监听程序,在程序启动时,启动socket监听.我们的应用场景是在java项目中,需要外接 ...

  9. php socket 多次发送,php模拟socket 多次发送数据的实现方法

    php模拟socket 多次发送数据的实现 方法 表四:Socket函数 函数名描述 socket_accept() 接受一个Socket连接 socket_bind() 把socket绑定在一个IP ...

最新文章

  1. readline 库简写版本,测试可用
  2. 280. Wiggle Sort
  3. 专栏 | 基于 Jupyter 的特征工程手册:数据预处理(二)
  4. php获取文件上传进度,PHP使用APC获取上传文件进度
  5. ue4 无限地图_UE4大地图(流关卡、无缝地图)
  6. C语身教程第三章: C说话挨次筹算匹面(1)
  7. 给要学习.NET(c#语言)的新手一些学习方法
  8. Jdb命令 The Java Debugger
  9. SCVMM2012 SP1 之P2V转换
  10. ios9提取安装包ipa_iOS 应用降级与 IPA 安装包备份
  11. 查看历史影像图卫星地图的方法
  12. linux文件类型elf,Linux下ELF文件的格式(1)
  13. ensp运行出现please check whether virtual box is installed 解决方法
  14. 【Axure原型图】——动态面板
  15. 华硕开机时出现无法验证数字签名驱动
  16. QLabel的四种显示方式
  17. java request修改uri,spring cloud zuul过滤器修改requestURI 忽略大小写
  18. 【斐波那契数列】10题-斐波那契数列
  19. 宽屏php模板,宽屏简洁工业网站前端模板
  20. 《Delphi传奇》研究系列文章1:服务端控制中心(服务器网关启动器)

热门文章

  1. js中写java集合代码,JS实现JAVA的List功能
  2. webpackjsonp 还原_具有催化CO2还原性能的非贵金属配合物的配体设计
  3. Java IO - Reader
  4. c mysql日期时间格式_mysql日期和时间类型
  5. js 数组 ajax php,js里面的对象ajax post到php端直接变成数组了?
  6. 收藏:深度剖析产品经理的「核心竞争力」
  7. python 定义字符串变量_python 字符串(1)
  8. iphone黑屏转圈_iphone XR被曝新BUG,众多用户中招,无规律黑屏假死
  9. oracle19c方言,JFinal框架操作oracle数据库
  10. java mongo subtract_春数据MongoDB的聚合框架,例外