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

golang 墙上时钟与单调时钟的实现

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

北京

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

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

看不清楚,换张图片

免费获取短信验证码

golang 墙上时钟与单调时钟的实现

墙上时钟与单调时钟

墙上时钟

墙上时钟也称为墙上时间。大多是1970年1月1日(UTC)以来的秒数和毫秒数。

墙上时间可以和NTP(Network Time Protocal,网络时间协议)同步,但是如果本地时钟远远快于NTP服务器,则强制重置之后会跳到先前某个时间点。(这里不是很确定,猜测是如果时间差的不多,则调整石英晶体振荡器的频率,慢慢一致。如果差很多,则强行一致)

单调时钟

机器大多有自己的石英晶体振荡器,并将其作为计时器。单调时钟的绝对值没有任何意义,根据操作系统和语言的不同,单调时钟可能在程序开始时设为0、或在计算机启动后设为0等等。但是通过比较同一台计算机上两次单调时钟的差,可以获得相对准确的时间间隔。

Time的结构

 type Time struct {
    // wall and ext encode the wall time seconds, wall time nanoseconds,
    // and optional monotonic clock reading in nanoseconds.
    //
    // From high to low bit position, wall encodes a 1-bit flag (hasMonotonic),
    // a 33-bit seconds field, and a 30-bit wall time nanoseconds field.
    // The nanoseconds field is in the range [0, 999999999].
    // If the hasMonotonic bit is 0, then the 33-bit field must be zero
    // and the full signed 64-bit wall seconds since Jan 1 year 1 is stored in ext.
    // If the hasMonotonic bit is 1, then the 33-bit field holds a 33-bit
    // unsigned wall seconds since Jan 1 year 1885, and ext holds a
    // signed 64-bit monotonic clock reading, nanoseconds since process start.
    wall uint64
    ext  int64
    ...
 }
复制代码

wall和ext共同记录了时间,但是分为两种情况,一种是没有记录单调时钟(比如是通过字符串解析得到的时间),另一种是记录了单调时钟(比如通过Now)。

wall的第一位是一个标记位

如果为1,则表示记录了单调时钟。则wall的2-34(闭区间)位记录了从1885-1-1到现在的秒数,最后30位记录了纳秒数。而ext记录了从程序开始运行到现在经过的单调时钟数。

如果为0,则表示没有记录单调时钟。则wall的2-34(闭区间)位全部为0(那最后30位是啥?)。而ext记录了从1-1-1到现在经过的秒数。

Since的实现

这里比较关键的代码是第914行的runtimeNano() - startNanostartNano的含义还是直接上代码比较明了。

 var startNano = 0
 ​
 func init(){
     startNano = runtimeNano()
 }

runtimeNano()是调用了汇编,获取了操作系统当前的单调时钟。前面说过,单调时钟的绝对值没有什么意义。因此这里将两个时间相减,得到了从程序开始到现在的单调时钟。

然后看一下Sub

 func (t Time) Sub(u Time) Duration {
    if t.wall&u.wall&hasMonotonic != 0 {
       te := t.ext
       ue := u.ext
       d := Duration(te - ue)
       if d < 0 && te > ue {
          return maxDuration // t - u is positive out of range
       }
       if d > 0 && te < ue {
          return minDuration // t - u is negative out of range
       }
       return d
    }
    d := Duration(t.sec()-u.sec())*Second + Duration(t.nsec()-u.nsec())
    // Check for overflow or underflow.
    switch {
    case u.Add(d).Equal(t):
       return d // d is correct
    case t.Before(u):
       return minDuration // t - u is negative out of range
    default:
       return maxDuration // t - u is positive out of range
    }
 }

这里我们只需要关注2-13行即可。除去了范围检查,这里的主要逻辑就是两个Time的ext相减。而ext又都代表了单调时钟,所以最后返回的是单调时钟的差值。

小结

在分布式系统中,我们经常需要判断时间间隔来检测心跳。而墙上时钟与NTP的组合可能会带来时间的前后跳跃与闪烁,所以使用单调时钟更加安全和保险。

在go语言中,没有直接调用调用时钟的函数。可以通过time.Now()获得带单调时钟的Time结构体,并通过Since和Until获得相对准确的时间间隔。

参考资料

go time分析

一个commit

go1.14.2 源码

数据密集型应用系统设计(书)

到此这篇关于golang 墙上时钟与单调时钟的实现的文章就介绍到这了,更多相关golang 墙上时钟与单调时钟内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

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

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

golang 墙上时钟与单调时钟的实现

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

下载Word文档

猜你喜欢

CSS3+js如何实现简单的时钟特效

小编给大家分享一下CSS3+js如何实现简单的时钟特效,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!什么是csscss是一种用来表现HTML或XML等文件样式的计算机语言,主要是用来设计网页的样式,使网页更加美化。它也是一
2023-06-09

Android怎么实现简单时钟View的方法

这篇文章给大家分享的是有关Android怎么实现简单时钟View的方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。通过Canvas的平移与旋转简化绘图逻辑是一个非常有用的技巧,下面的时钟view就是利用这个方法
2023-05-30

Go中使用单调时钟获得准确的时间间隔问题

目录墙上时钟与单调时钟墙上时钟单调时钟Time的结构Since的实现小结参考资料墙上时钟与单调时钟 墙上时钟 墙上时钟也称为墙上时间。大多是1970年1月1日(UTC)以来的秒数和毫秒数。 墙上时间可以和NTP(Network Time P
2022-06-07

python怎么实现好看的时钟效果

这篇文章主要介绍“python怎么实现好看的时钟效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“python怎么实现好看的时钟效果”文章能帮助大家解决问题。游戏用到初高中使用的三角函数等知识开发,
2023-06-30

C#如何实现图形界面的时钟

今天小编给大家分享一下C#如何实现图形界面的时钟的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。秒针有跳跃两个格子问题,主要是
2023-07-02

Win10预览版10056调整了开始菜单、时钟的位置

从近日曝光的Windows 10 build 10056来看,javascript微软对这套系统的改进做得还算是相当不错。在build 10056当中,我们可以看到开始菜单上的小按钮php,当用户将鼠标放在“电源”上
2023-06-13

如何使用MySQL和Ruby实现一个简单的时钟功能

如何使用MySQL和Ruby实现一个简单的时钟功能时钟功能在各种应用中经常会被使用到,它可以帮助我们记录时间、计时、定时等。在本文中,我们将介绍如何使用MySQL和Ruby来实现一个简单的时钟功能,并提供相应的代码示例。首先,我们需要创建一
2023-10-22

如何通过Canvas+JS实现简易的时钟

今天就跟大家聊聊有关如何通过Canvas+JS实现简易的时钟,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。之前学习了下html5中的canvas元素,为了练练手就实现了一个简易的时钟
2023-06-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录