gpt4 book ai didi

timer - goroutines 中的 golang 计时器阻塞

转载 作者:IT王子 更新时间:2023-10-29 01:37:01 26 4
gpt4 key购买 nike

以下代码来自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")
}
}

如果我运行上面的代码,输出将是这样的(结果一):

Timer 1 expired
Timer 2 stopped

但是如果我将匿名函数的主体更改为:

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

输出仍然像以前一样。我很困惑,为什么第二个输出不像(结果二):

Timer 1 expired
Timer 2 expired
Timer 2 stopped

根据我的理解,<-timer2.C 会阻止 goroutine 的剩余部分,直到计时器 channel 获得一个值,所以如果我输入 fmt.Printf("Timer 2 expired")<-timer2.C 之后输出会喜欢结果一,但是如果我在 <- timer2.C,我觉得打印 Action 不会被阻塞

希望有人能帮帮我,谢谢大家。

最佳答案

问题很可能是没有保证 "happens before"打印语句和程序结束之间的关系。当main Goroutine退出时,整个程序退出。

Goroutines 有一个启动时间,运行时有几个标准来决定何时切换到另一个正在运行的 goroutine。可能发生的情况是匿名函数中没有任何代码被执行,因为主 goroutine 没有任何阻塞操作(甚至昂贵的函数调用),很快退出

改变 GOMAXPROCS,就像这个程序试图做的那样,有时可以“修复”这个问题,因为多个线程有一个机会潜入一些代码,因为它们不必须依赖运行时的显式上下文切换,但没有保证“发生在之前”的关系,或者至少至少没有一些语句故意让主 goroutine 挂起一段时间(例如空的 select{}for{} 等)你不能依赖主 goroutine 之外的任何实际运行的代码。

完全有可能在一台完全不同的机器上(或者甚至是同一台机器,但负载较小,或超频或...),您会得到您期望的行为。不幸的是,正如您了解到的那样,您不能指望它,因此请确保同步您的 goroutine。

关于timer - goroutines 中的 golang 计时器阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23947770/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com