douliu7929 2014-05-29 21: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-29 21: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.

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

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部