zoukankan      html  css  js  c++  java
  • golang 中的 time 包的 Ticker

    真实的应用场景是:在测试收包的顺序的时候,加了个 tick 就发现丢包了

    那么来看一个应用例子:

    package main
    
    import (
        "fmt"
        "runtime"
        "time"
    )
    
    func init() {
        runtime.GOMAXPROCS(runtime.NumCPU())
    }
    
    func main() {
        ch := make(chan int, 1024)
        go func(ch chan int) {
            for {
                val := <-ch
                fmt.Printf("val:%d
    ", val)
            }
        }(ch)
    
        tick := time.NewTicker(1 * time.Second)
        for i := 0; i < 20; i++ {
            select {
            case ch <- i:
            case <-tick.C:
                fmt.Printf("%d: case <-tick.C
    ", i)
            }    
    
            time.Sleep(200 * time.Millisecond)
        }
        close(ch)
        tick.Stop()
    }

    输出结果如下:

    val:0
    val:1
    val:2
    val:3
    val:4
    val:5
    6: case <-tick.C
    val:7
    val:8
    val:9
    10: case <-tick.C
    val:11
    val:12
    val:13
    val:14
    15: case <-tick.C
    val:16
    val:17
    val:18
    val:19
    

    问题出在这个select里面:

    select {
        case ch <- i:
        case <-tick.C:
          fmt.Printf("%d: case <-tick.C
    ", i)
    }

      [tick.C 介绍说明] 当两个 case 条件都满足的时候,运行时系统会通过一个伪随机的算法决定哪个case将会被执行。所以当 tick.C 条件满足的那个循环,有某种概率造成 ch<-i 没有发送(虽然通道两端没有阻塞,满足发送条件)

     解决方案1:一旦 tick.C 随机的 case 被随机到,就多执行一次 ch<-i (不体面,如果有多个case就不通用了)

    select {
        case ch <- i:
        case <-tick.C:
            fmt.Printf("%d: case <-tick.C
    ", i)
            ch <- i
    }

       解决方案2:将tick.C的case单独放到一个select里面,并加入一个default(保证不阻塞)

    select {
        case ch <- i:
    }
    select {
        case <-tick.C:
            fmt.Printf("%d: case <-tick.C
    ", i)
        default:
    }

    两种解决方案的输出都是希望的结果:

    val:0
    val:1
    val:2
    val:3
    val:4
    5: case <-tick.C
    val:5
    val:6
    val:7
    val:8
    val:9
    10: case <-tick.C
    val:10
    val:11
    val:12
    val:13
    val:14
    15: case <-tick.C
    val:15
    val:16
    val:17
    val:18
    val:19
  • 相关阅读:
    大数据概述 106
    编译原理学习随笔 106
    我与ruby第一次接触
    xml在joomla表单中的应用详解
    joomla2.5传统组件开发解析
    joomla2.5开发系列教程原创(1)2.5与1.5异同点
    CSS2简写和常用css总结笔记
    C语言开发php扩展链接库初学
    ruby转战Ubuntu,真折腾?
    joomla搜索功能开发和结果分页探讨
  • 原文地址:https://www.cnblogs.com/liang1101/p/7630002.html
Copyright © 2011-2022 走看看