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.