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

8c1748e2f1657d17bc04831a5ed95212.png

前言:

最近在啃《 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所有取值,然后生成曲线图,就很明白了:

6f9faa399e3c41bc24531ae54ecf73a7.png

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

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

bfba5dcd9e178eedce293f275f5b70bf.png


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

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

e27dbdea17d612c5ad024f8225bc4d18.png


这种情况下同情况1。

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

78d0a7754018c8478054c0f26a07f12f.png


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

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

c76755ef854b92707b20ba845ffc4f85.png

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

edd748595e041dd97c02e302cab3e9a0.png


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

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

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

总结:

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/365362.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET Core Razor Pages

Razor 页面是Asp.Net Core2.0新增的一个功能。Razor 页面是 ASP.NET Core MVC 的一个新特性&#xff0c;它可以使基于页面的编码方式更简单高效。 环境&#xff1a;vs2017 .net core2.2 Razor 页面项目搭建 目录说明 wwwroot&#xff1a;放置网站的静态文件的目录。例如/wwwroo…

curd操作php代码,Laravel 5.6中的CURD操作(代码示例详解)

在本篇文章中&#xff0c;我将给大家分享laravel 5.6版本中的基本crud(创建&#xff0c;读取&#xff0c;更新和删除)应用程序模块。你可以按照下面的步骤在laravel 5.6中创建CRUD应用程序。Laravel是一个流行的开源PHP MVC框架&#xff0c;具有许多高级开发功能。如果你是lara…

为什么c++的开源库那么少?

为什么c的开源库那么少&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「 C的资料从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全部无偿共享给大家&#xff01;&#xff01;…

页面静态化+过期时间

代码&#xff1a; <?phpHeader("content-type:text/html;charsetUTF-8");$gid $_GET[news_id]0;//商品id$goods_statis_file "goods_file_".$gid.".html";//对应静态页文件$expr 10;//静态文件有效期&#xff0c;秒if(file_exists($goods…

实施动态代理-比较

有时需要拦截某些方法调用&#xff0c;以便每次调用被拦截方法时都执行自己的逻辑。 如果您不属于Java EE的CDI领域&#xff0c;并且不想使用诸如Aspectj之类的AOP框架&#xff0c;那么您将有一个简单而有效的替代方法。 从1.5版开始&#xff0c;JDK附带了类java.lang.reflect…

结构专业规范大全_1.2万篇 建筑行业规范大全套!速来!

应广大站友以及会员用户对建筑规范的要求&#xff0c;我们整理了近几年来国家发布的各个专业的标准、规范、图集&#xff0c;以及全国各地共32个地区的区域标准&#xff0c;总计12000余篇&#xff0c;共计80G的建筑行业规范&#xff01;BIMer自学站将会在一到两个月的之间内相继…

数据库如何进行索引优化

数据库索引 1&#xff0e;什么是索引 在数据库中&#xff0c;索引的含义与日常意义上的“索引”一词并无多大区别&#xff08;想想小时候查字典&#xff09;&#xff0c;它是用于提高数据库表数据访问速度的数据库对象。A&#xff09;索引可以避免全表扫描。多数查询可以仅扫描…

php7如何安装swoole,PHP7如何安装Swoole?

PHP7如何安装Swoole&#xff1f;发布时间&#xff1a;2020-05-19 16:35:02来源&#xff1a;亿速云阅读&#xff1a;135作者&#xff1a;Leah这篇文章给大家分享的是PHP7安装Swoole的详细安装教程&#xff0c;相信大部分人都还不知道怎么安装&#xff0c;为了让大家学会&#xf…

第二章总结

第二章 寄存器 1.CPU概述 一个典型的CPU由运算器、控制器、寄存器等器件组成。 内部总线实现CPU内部各个器件之间的联系。 外部总线实现CPU和主板上其它器件的联系。 2.通用寄存器 8086CPU中&#xff0c;寄存器AX, BX, CX, DX通常用于存放一般性数据&#xff0c;称为通用寄存器…

赞!15个来自 CodePen 的酷炫 CSS 动画效果

CodePen 是一个在线的前端代码编辑和展示网站&#xff0c;能够编写代码并即时预览效果。你在上面可以在线分享自己的 Web 作品&#xff0c;也可以欣赏到世界各地的优秀开发者在网页中实现的各种令人惊奇的效果。 今天这篇文章为大家挑选了15个超炫的 CSS 动画效果的例子&#x…

Java 8 Friday Goodies:新的新I / O API

在Data Geekery &#xff0c;我们喜欢Java。 而且&#xff0c;由于我们真的很喜欢jOOQ的流畅的API和查询DSL &#xff0c;我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 我们已经写了一些关于Java 8好东西的博客 &#xff0c;现在我们觉得是时候开始一个新的博客系列了…

ashly理器4.8软件汉化版_AMD 处理器核心比英特尔多还更便宜?英特尔回应

IT之家 9 月 25 日消息 英特尔已在本月初发布了 11 代酷睿移动处理器&#xff0c;搭载 11 代酷睿的产品最早将在 10 月上市。现在&#xff0c;新浪科技访了英特尔公司中国零售销售集团总经理唐炯&#xff0c;就 11 代酷睿产品进行讨论。在谈到 AMD 处理器比英特尔便宜&#xff…

JAVA比较两个List集合的方法

import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set;public class FindNumber { public static void main(String[] args) { // 注意&#xff1a;一定要使用创建对象…

js 解析php serialize,php如何解析jquery serialize 提交后的数据

客户端通过jquery serialize 提交表单数据$("#submit_survey").click(function(){ $.post(SITE_URLactivity/survey/savesurvey, {data:$(#survey_form).serialize()}, function(response){ if (response.error_code) { infotips(response.msg, $(.submit_tips)); } …

OutOfMemoryError:解决方案反模式

这些年来&#xff0c;我们一直密切关注以OutOfMemoryError消息的不同形式打包的问题。 通过专门的服务&#xff08;例如Google警报&#xff09;&#xff0c;每天就特定关键字的新问题进行摘要&#xff0c;使我们对应用程序因日志中的java.lang.OutOfMemoryError失败而出现的情况…

python在线问卷调查系统源代码_基于Python 练习1情况的在线问卷

Q1. 您每个月的生活费是&#xff1f;(单选题)Q2. 您在职的职位是&#xff1a;(单选题)Q3. 您的家庭背景&#xff1f;(单选题)Q4. 下列哪一个是Python中正确的变量名&#xff1f;()(单选题)A Sprout*1B 1SproutC Sprout 1D Sprout_1Q5. Turtle 中的 Write 命令是用来做什么的 ()…

leetcood学习笔记-58-最后一个单词的长度

题目描述&#xff1a; 第一次解答&#xff1a; class Solution:def lengthOfLastWord(self, s: str) -> int:Ls.strip().split(" ")if L[-1]"" :return 0return len(L[-1]) 优化后&#xff1a; class Solution:def lengthOfLastWord(self, s: str) ->…

Plyr – 简单,灵活的 HTML5 媒体播放器

Plyr 是一个简单的 HTML5 媒体播放器&#xff0c;包含自定义的控制选项和 WebVTT 字幕。它是只支持现代浏览器&#xff0c;轻量&#xff0c;方便和可定制的媒体播放器。还有的标题和屏幕阅读器的全面支持。 在线演示 源码下载 您可能感兴趣的相关文章网站开发中很有用的 …

第一章 SpringBoot快速入门

1.1、包依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.14.RELEASE</version><relativePath/> <!-- lookup parent from repository --> …

使用Redis的简单消息队列

在本文中&#xff0c;我们将使用列表命令将Redis用作简单的消息队列。 假设我们有一个允许用户上传照片的应用程序。 然后在应用程序中&#xff0c;我们以不同大小显示照片&#xff0c;例如Thumb&#xff0c;Medium和Large。 在第一个实现中&#xff0c;我们可以承担在同一请…