See also: https://github.com/golang/go/issues/10958
On Wednesday, June 21, 2017 at 1:12:12 AM UTC-4, Ronald wrote: > > 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.