douliu7929 2014-05-30 05:38
浏览 41
已采纳

goroutines中的golang计时器阻止

Below code is from go by example - timers

package main

import (
    "time"
    "fmt"
)

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    timer1 := time.NewTimer(time.Second * 1)

    <-timer1.C
    fmt.Println("Timer 1 expired")

    timer2 := time.NewTimer(300) //change the duration to be more shorter
    go func() {
        <-timer2.C
        fmt.Printf("Timer 2 expired")
    }()

    stop2 := timer2.Stop()
    if stop2 {
        fmt.Printf("Timer 2 stopped")
    }
}

If I run above code, the output will be like(result one):

Timer 1 expired
Timer 2 stopped

but if I change the body of the anonymous func to be:

fmt.Printf("Timer 2 expired")
<-timer2.C

the output is still like before. I'm confused, why the second output is not like(result two):

Timer 1 expired
Timer 2 expired
Timer 2 stopped

As per my understanding <-timer2.C blocks the remain of goroutine until the timer channel get a value, so if I put fmt.Printf("Timer 2 expired") after <-timer2.C the output will like result one, but if I put fmt.Printf("Timer 2 expired") before <-timer2.C, I think the print action will not be blocked.

Hope someone could give me a hand, thank you all.

  • 写回答

1条回答 默认 最新

  • douqie3391 2014-05-30 05:59
    关注

    The problem is likely that there's no guaranteed "happens before" relationship between the print statement and the end of the program. When the main Goroutine exits, the whole program exits.

    Goroutines have a startup time, and the runtime has several criteria for when it switches to another running goroutine. What's probably happening is that no code in the anonymous function is ever being executed, because the main goroutine, lacking any blocking operations (or even expensive function calls), exits very quickly

    Changing GOMAXPROCS, as this program attempts to do, can sometimes "fix" that, in that the multiple threads have a chance of sneaking in some code because they don't have to rely on an explicit context switch from the runtime, but without a guaranteed "happens before" relationship, or at least without some statement to intentionally make the main goroutine hang for a while (e.g. the empty select{}, for{} etc) you can't rely on any code outside the main goroutine ever actually running.

    It's entirely possible that on a completely different machine (or even the same machine with less load, or overclocked or...), you'd get the behavior that you expect. Unfortunately since, as you learned, you can't count on it, make sure you synchronize your goroutines.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 CSS实现渐隐虚线边框
  • ¥15 thinkphp6配合social login单点登录问题
  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题