zoukankan      html  css  js  c++  java
  • 标准库 time

    go语言的time包

    1. 组成

    time.Duration(时长,耗时)

    time.Time(时间点)
    time.C(放时间点的管道)[ Time.C:=make(chan time.Time) ]
    time包里有2个东西,一个是时间点,另一个是时长
    时间点的意思就是“某一刻”,比如 2000年1月1日1点1分1秒 那一刻(后台记录的是unix时间,从1970年开始计算)
    时长就是某一刻与另一刻的差,也就是耗时

    2. 函数

    2.1 Sleep函数

    time.Sleep(time.Duration) 
    表示睡多少时间,睡觉时,是阻塞状态

    fmt.Println("start sleeping...")
    time.Sleep(time.Second)
    fmt.Println("end sleep.")
    //【结果】打印start sleeping后,等了正好1秒后,打印了end sleep

    time.Sleep单位为:1ns (纳秒),通常这样用:time.Sleep(3*time.Second)不直接填数字

    转换单位:

          1纳秒 =1000皮秒
          1纳秒 =0.001 微秒
          1纳秒 =0.000 001毫秒   
          1纳秒 =0.000 000 001秒

    写无限循环代码的时候老是担心 time.sleep时间过短或者过长的影响 于是乎就测试了下

    结果终于安心了,原来这是有瓶颈的。

    package main  
    import(  
        "fmt"  
        "time"  
    )  
    func main(){  
        fmt.Println(int(time.Second))  
        forNum:=10000  
        test1(1000000,forNum)  
        test1(1000,forNum)  
        test1(1,forNum)  
          
    }  
      
    func test1(sleepTime time.Duration,num int){  
        i:=0  
        t := time.Now()  
        for{  
            i++  
            if i>=num{  
                fmt.Println("forNum:",num," sleep:",sleepTime," use:",time.Now().Sub(t).String())  
                break  
            }  
            time.Sleep(sleepTime)  
        }  
    }  
    

      运行结果:

    1000000000
    forNum: 10000  sleep: 1ms  use: 13.6380121s
    forNum: 10000  sleep: 1µs  use: 13.421951s
    forNum: 10000  sleep: 1ns  use: 13.4345272s
    成功: 进程退出代码 0.
    

     sleep会让你逻辑的运算变慢 但是降低CPU消耗

    如果不进行sleep CPU消耗会上去,但是运算速度超快,可以把sleep注释掉看看

    基本 时间成本忽略不计。

    所以sleep的使用 应该是策略性的。

    2.2 After函数

    time.After(time.Duration) 
    和Sleep差不多,意思是多少时间之后,但在取出管道内容前不阻塞

    fmt.Println("the 1")
    tc:=time.After(time.Second) //返回一个time.C这个管道,1秒(time.Second)后会在此管道中放入一个时间点(time.Now())
                            //时间点记录的是放入管道那一刻的时间值
    fmt.Println("the 2")
    fmt.Println("the 3")
    <-tc   //阻塞中,直到取出tc管道里的数据
    fmt.Println("the 4")
    //【结果】立即打印123,等了1秒不到一点点的时间,打印了4,结束
    //打印the 1后,获得了一个空管道,这个管道1秒后会有数据进来
    //打印the 2,(这里可以做更多事情)
    //打印the 3
    //等待,直到可以取出管道的数据(取出数据的时间与获得tc管道的时间正好差1秒钟)
    //打印the 4
    

      

    fmt.Println("the 1")
    tc:=time.After(time.Second) //返回一个time.C这个管道,1秒(time.Second)后会在此管道中放入
                            //一个时间点(time.Now()),时间点记录的是放入管道那一刻的时间值
    fmt.Println("the 2")
    fmt.Println("the 3")
    time.Sleep(time.Second*0.5)//这里是假设这个Println动作执行了半秒钟
    fmt.Println("the 4")
    time.Sleep(time.Second*0.5)//这里是假设这个Println动作执行了半秒钟
    fmt.Println("the 5")
    fmt.Println("the 6")
    fmt.Println("the 7")
    <-tc   //阻塞中,直到取出tc管道里的数据
    fmt.Println("the 8")
    //【结果】立即打印1和2,花了半秒打印了3和4,然后又立即打印了5678,结束
    //这里的<-tc是立即能获得数据的
    //因为早在执行差不多Print 6的时候,管道内已经有数据了
    //当gorotine线把数据丢到管道中后,它自己阻塞了(具体请了解goroutine)
    

      

    2.3 AfterFunc函数

    time.AfterFunc(time.Duration,func()) 
    和After差不多,意思是多少时间之后在goroutine line执行函数

    f := func() {
        fmt.Println("Time out")
    }
    time.AfterFunc(1*time.Second, f)
    time.Sleep(2 * time.Second) //要保证主线比子线“死的晚”,否则主线死了,子线也等于死了
    //【结果】运行了1秒后,打印出timeout,又过了1秒,程序退出
    //将一个间隔和一个函数给AfterFunc后
    //间隔时间过后,执行传入的函数
    

      

    由于f函数不是在Main Line执行的,而是注册在goroutine Line里执行的 
    所以一旦后悔的话,需要使用Stop命令来停止即将开始的执行,如果已经开始执行就来不及了

    houhui := true
    f := func() {
        fmt.Println("Time out")
    }
    ta := time.AfterFunc(2*time.Second, f)
    time.Sleep(time.Second)
    if houhui {
        ta.Stop()
    }
    time.Sleep(3 * time.Second)    //要保证主线比子线“死的晚”,否则主线死了,子线也等于死了
    //【结果】运行了3秒多一点点后,程序退出,什么都不打印
    //注册了个f函数,打算2秒后执行
    //过了1秒后,后悔了,停掉(Stop)它

    2.4 Tick函数

    time.Tick(time.Duration) 
    和After差不多,意思是每隔多少时间后,其他与After一致

    fmt.Println("the 1")
    tc:=time.Tick(time.Second) //返回一个time.C这个管道,1秒(time.Second)后会在此管道中放入一个时间点,
                            //1秒后再放一个,一直反复,时间点记录的是放入管道那一刻的时间
    for i:=1;i<=2;i++{
        <-tc
        fmt.Println("hello")
    }
    //每隔1秒,打印一个hello
    

      

    3. time.Time的方法

    3.1 Before & After方法

    判断一个时间点是否在另一个时间点的前面(后面),返回true或false

    t1:=time.Now()
    time.Sleep(time.Second)
    t2:=time.Now()
    a:=t2.After(t1)     //t2的记录时间是否在t1记录时间的**后面**呢,是的话,a就是true
    fmt.Println(a)       //true
    b:=t2.Before(t1)     //t2的记录时间是否在t1记录时间的**前面**呢,是的话,b就是true
    fmt.Println(b)       //false

    3.2 Sub方法

    两个时间点相减,获得时间差(Duration)

    t1:=time.Now()
    time.Sleep(time.Second)
    t2:=time.Now()
    d:=t2.Sub(t1)     //时间2减去时间1
    fmt.Println(d)       //打印结果差不多为1.000123几秒,因为Sleep无法做到精确的睡1秒
    后发生的时间  减去   先发生时间,是正数

    3.3 Add方法

     拿一个时间点,add一个时长,获得另一个时间点

    t1:=time.Now()              //现在是12点整(假设),那t1记录的就是12点整
    t2:=t1.Add(time.Hour)          //那t1的时间点 **加上(Add)** 1个小时,是几点呢?
    fmt.Println(t2)       //13点(呵呵)
    

      转自:https://my.oschina.net/u/943306/blog/149395

  • 相关阅读:
    【BUG修复】视频综合管理平台EasyNVS首页设备接入情况显示与实际不符如何调整?
    数据库连接池
    手写SORM(simple object relation mapping)框架3—DBManager和TableContext的设计
    jdbc—总结
    jdbc—CLOB和BLOB
    jdbc—时间处理
    jdbc—事务
    递归(最大公约数)
    C++ return
    函数参数
  • 原文地址:https://www.cnblogs.com/yorkyang/p/8135900.html
Copyright © 2011-2022 走看看