go - golang timer blocking in goroutines -
below code go 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 duration more shorter go func() { <-timer2.c fmt.printf("timer 2 expired") }() stop2 := timer2.stop() if stop2 { fmt.printf("timer 2 stopped") } }
if run above code, output like(result one):
timer 1 expired timer 2 stopped
but if change body of anonymous func be:
fmt.printf("timer 2 expired") <-timer2.c
the output still before. i'm confused, why second output not like(result two):
timer 1 expired timer 2 expired timer 2 stopped
as per understanding <-timer2.c blocks remain of goroutine until timer channel value, if put fmt.printf("timer 2 expired") after <-timer2.c output result one, if put fmt.printf("timer 2 expired") before <-timer2.c, think print action not blocked.
hope give me hand, thank all.
the problem there's no guaranteed "happens before" relationship between print statement , end of program. when main goroutine exits, whole program exits.
goroutines have startup time, , runtime has several criteria when switches running goroutine. what's happening no code in anonymous function ever being executed, because main goroutine, lacking blocking operations (or expensive function calls), exits quickly
changing gomaxprocs
, program attempts do, can "fix" that, in multiple threads have chance of sneaking in code because don't have rely on explicit context switch runtime, without guaranteed "happens before" relationship, or @ least without statement intentionally make main goroutine hang while (e.g. empty select{}
, for{}
etc) can't rely on code outside main goroutine ever running.
it's entirely possible on different machine (or same machine less load, or overclocked or...), you'd behavior expect. unfortunately since, learned, can't count on it, make sure synchronize goroutines.
Comments
Post a Comment