I found this: https://github.com/golang/go/issues/7190.
Then I replace : go func() { for { } }() With: go func() { ct := 0 t1 := time.Now().UnixNano() for { ct++ if ct%600000000 == 0 { t2 := time.Now().UnixNano() fmt.Println("hooray", t2, t1, float64(t2-t1)/1e6) t1 = t2 } } }() Thus the program does not stuck anymore -- *But it is thrashing * *and churning*! (With a time delay nearly 100-200ms based on value '600000000' and the speed of your computer) So I 'upgrade' the code again with: go func() { ct := 0 t1 := time.Now().UnixNano() for { ct++ if ct%100000 == 0 { runtime.Gosched() } if ct%600000000 == 0 { t2 := time.Now().UnixNano() fmt.Println("hooray", t2, t1, float64(t2-t1)/1e6) t1 = t2 } } }() Then it looks just fine.But a pretty serious question emerged: P1: No matter how much the GOMAXPROCS is, if you run a very CPU intensive go routine, your system will become definitely thrashing and churning, and the time delay is depending on how intensive you go code is. *Is proposition P1 is always true on golang so far*? If P1 is true, as the GOMAXPROCS is bigger than 1, can't the scheduler rearrange the waiting staff (including pending go routines and other core business) to other idle threads when some 'indecency' goroutine is seizing the several busiest threads? On Wednesday, 21 June 2017 11:45:20 UTC+8, Ronald wrote: > > PS: > > go func() { > for { > } > }() > > > The reason of this code above is that I want to test the channel's latency > when some 'indecency' goroutine is seizing several whole OS threads. > > On Wednesday, 21 June 2017 11:40:12 UTC+8, Ronald wrote: >> >> Hi, I found when running this code below (play >> <https://play.golang.org/p/XyxV_1f6Ri>): >> >> >> package main >> import "fmt" >> import "runtime" >> import "time" >> type callRet struct { >> ret int >> } >> type callIn struct { >> ret_chan chan *callRet >> arg1 int >> } >> func caller(call_in_c chan *callIn, arg1 int) int { >> ret_c := make(chan *callRet, 1) >> ci := callIn{ret_c, arg1} >> t1 := time.Now().UnixNano() >> call_in_c <- &ci >> ret := <-ret_c >> t2 := time.Now().UnixNano() >> _, _ = t1, t2 >> //fmt.Println(t2, t1, float64(t2-t1)/1e6) >> return ret.ret >> } >> func call_srv(call_in_c chan *callIn) { >> //runtime.LockOSThread() >> ct := 0 >> for { >> select { >> case in := <-call_in_c: >> ret_c := in.ret_chan >> ret := callRet{3 + in.arg1} >> ret_c <- &ret >> ct++ >> if ct%1000 == 0 { >> fmt.Println(ct) >> } >> //default: >> // time.Sleep(1 * time.Millisecond) >> } >> } >> //runtime.UnlockOSThread() >> } >> func init() { >> //runtime.LockOSThread() >> } >> func main() { >> p := fmt.Println >> runtime.GOMAXPROCS(5) >> call_in_c := make(chan *callIn, 2000) >> fp := func(call_in_c chan *callIn) { >> ct := 0 >> for ; ct < 2000000; ct = ct + 1 { >> caller(call_in_c, 1) >> time.Sleep(100 * time.Nanosecond) >> } >> p("done:)") >> } >> go fp(call_in_c) >> go fp(call_in_c) >> go func() { >> for { >> fmt.Println("heartbeat...") >> time.Sleep(10 * 1000 * time.Microsecond) >> } >> }() >> >> // after delete this little piece code, it will be ok >> >> go func() { >> for { >> } >> }() >> >> // -^ >> >> call_srv(call_in_c) >> return >> } >> >> It will always “stuck” in certain time after start executing (tested in >> both go 1.7 , 1.8.1 and 1.8.3, >> and you should run it on your own computer, not on the play because it >> would cost several seconds). >> I have checked the code above dozens of times at least and sure it is all >> right. >> >> I tried to attach the go process with gdb when it is stuck and the `bt` >> yielded this: >> >> >>> (gdb) info goroutines >>> 1 waiting runtime.gopark >>> 2 waiting runtime.gopark >>> 3 waiting runtime.gopark >>> 4 waiting runtime.gopark >>> 5 waiting runtime.gopark >>> * 6 running runtime.systemstack_switch >>> 7 waiting runtime.gopark >>> * 8 running main.main.func3 >>> 17 runnable runtime.exitsyscall >>> 33 waiting runtime.gopark >>> 18 waiting runtime.gopark >>> 49 waiting runtime.gopark >>> 50 waiting runtime.gopark >>> 51 waiting runtime.gopark >>> (gdb) goroutine 6 bt >>> #0 runtime.systemstack_switch () at >>> /usr/local/go/src/runtime/asm_amd64.s:281 >>> #1 0x0000000000415088 in runtime.gcStart (mode=0, forceTrigger=false) >>> at /usr/local/go/src/runtime/mgc.go:1010 >>> #2 0x000000000040d841 in runtime.mallocgc (size=96, typ=0x4a7fa0, >>> needzero=true, >>> ~r3=0x507998 <runtime.timers+24>) at >>> /usr/local/go/src/runtime/malloc.go:785 >>> #3 0x000000000040df68 in runtime.newobject (typ=0x4a7fa0, ~r1=0x0) >>> at /usr/local/go/src/runtime/malloc.go:820 >>> #4 0x00000000004035d2 in runtime.makechan (t=0x492960, size=1, >>> ~r2=0xc4200016c0) >>> at /usr/local/go/src/runtime/chan.go:92 >>> #5 0x00000000004840e4 in main.caller (call_in_c=0xc420056060, arg1=1, >>> ~r2=0) >>> at /root/go/src/chan/x.go:18 >>> #6 0x00000000004846ac in main.main.func1 (call_in_c=0xc420056060) at >>> /root/go/src/chan/x.go:62 >>> #7 0x000000000044da21 in runtime.goexit () at >>> /usr/local/go/src/runtime/asm_amd64.s:2197 >>> #8 0x000000c420056060 in ?? () >>> #9 0x0000000000000000 in ?? () >> >> >> >> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.