golang gc stop the world how to stop cpu busy goroutine?

214 views
Skip to first unread message

刘桂祥

unread,
Sep 4, 2017, 1:46:47 AM9/4/17
to golang-nuts
when have one or two cpu busy goroutine in my server (example for loop empty),  the gc stop the world how to stop the goroutine ?

John Souvestre

unread,
Sep 4, 2017, 2:20:37 AM9/4/17
to golang-nuts

Although a goroutine isn’t pre-emptible by the Go scheduler, there is an opportunity whenever it does something which blocks or when it calls a non-inlined function.  So generally the GC’s STW can take place pretty quickly.  But if you are doing something with is totally compute bound then it can be a problem.  An easy solution is to insert a call to runtime.Gosched() every so often.

 

I believe that there is an ongoing discussion about a way for Go to plan ahead and be able to handle even these cases, but it’s something for the future.

 

John

    John Souvestre - New Orleans LA

--
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...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

刘桂祥

unread,
Sep 4, 2017, 3:09:50 AM9/4/17
to golang-nuts
package main

import "runtime"

// GOMAXPROCS=1
var sum1, summain int64

func add1() {
    for i := 0; i < 10000; i++ {
        for j := 0; j < 10000; j++ {
            sum1++
        }
    }
}

func bar() {
    for {
        add1()
    }
}

func main() {
    go bar()
    runtime.Gosched()
    println("debug>>>")
}

above is my example code,when I set GOMAXPROCS=1 and build with -gcflags "-N -l"  the println("debug>>>") don't  execute 
I just doubt the go runtime support peempt schedule in call function,   it don't work ??



在 2017年9月4日星期一 UTC+8下午2:20:37,John Souvestre写道:

John Souvestre

unread,
Sep 4, 2017, 3:25:04 AM9/4/17
to golan...@googlegroups.com

I think that you put the call to runtime.Gosched() in the wrong place.  You want to place it in the routine which needs to be pre-empted.  In your example, in add1() inside the “for i” loop or in bar() in the “for” loop.

刘桂祥

unread,
Sep 4, 2017, 3:41:58 AM9/4/17
to golang-nuts
Yes, I just want to let the bar func goroutine run first  or replace runtime.Gosched() with time.Sleep,
But I still doubt why add1 in bar func don't happen preempt schedule ?

在 2017年9月4日星期一 UTC+8下午3:25:04,John Souvestre写道:

John Souvestre

unread,
Sep 4, 2017, 3:54:13 AM9/4/17
to golan...@googlegroups.com

time.Sleep() will do the job, but you probably wouldn’t want to use it in a compute-bound loop.

 

Perhaps the call to add1() got inlined in bar().  The compiler might have simplified add1() first, since sum1 wasn’t being used anywhere.  Then perhaps it inlined what was left.

 

You might want to use sum1 by printing it (not inside the loop!).

刘桂祥

unread,
Sep 4, 2017, 4:00:08 AM9/4/17
to golang-nuts
But I build with -gcflags "-N -l"  
here is gdb code:
(gdb)
Dump of assembler code for function main.main:
   0x0000000000002100 <+0>: mov    %gs:0x8a0,%rcx
   0x0000000000002109 <+9>: cmp    0x10(%rcx),%rsp
   0x000000000000210d <+13>: jbe    0x216c <main.main+108>
   0x000000000000210f <+15>: sub    $0x18,%rsp
   0x0000000000002113 <+19>: mov    %rbp,0x10(%rsp)
   0x0000000000002118 <+24>: lea    0x10(%rsp),%rbp
   0x000000000000211d <+29>: movl   $0x0,(%rsp)
   0x0000000000002124 <+36>: lea    0x6abfd(%rip),%rax        # 0x6cd28 <main.bar.f>
   0x000000000000212b <+43>: mov    %rax,0x8(%rsp)
   0x0000000000002130 <+48>: callq  0x2bf60 <runtime.newproc>
   0x0000000000002135 <+53>: callq  0x253c0 <runtime.Gosched>
   0x000000000000213a <+58>: callq  0x242d0 <runtime.printlock>
   0x000000000000213f <+63>: lea    0x643b1(%rip),%rax        # 0x664f7 <go.string.*+967>
   0x0000000000002146 <+70>: mov    %rax,(%rsp)
   0x000000000000214a <+74>: movq   $0x8,0x8(%rsp)
   0x0000000000002153 <+83>: callq  0x24bf0 <runtime.printstring>
   0x0000000000002158 <+88>: callq  0x24550 <runtime.printnl>
   0x000000000000215d <+93>: callq  0x24360 <runtime.printunlock>
   0x0000000000002162 <+98>: mov    0x10(%rsp),%rbp
   0x0000000000002167 <+103>: add    $0x18,%rsp
   0x000000000000216b <+107>: retq
   0x000000000000216c <+108>: callq  0x493c0 <runtime.morestack_noctxt>
   0x0000000000002171 <+113>: jmp    0x2100 <main.main>
End of assembler dump.
(gdb) disas bar
No symbol "bar" in current context.
(gdb) disas main.bar
Dump of assembler code for function main.bar:
   0x00000000000020d0 <+0>: mov    %gs:0x8a0,%rcx
   0x00000000000020d9 <+9>: cmp    0x10(%rcx),%rsp
   0x00000000000020dd <+13>: jbe    0x20ec <main.bar+28>
   0x00000000000020df <+15>: jmp    0x20e1 <main.bar+17>
   0x00000000000020e1 <+17>: jmp    0x20e3 <main.bar+19>
   0x00000000000020e3 <+19>: callq  0x2040 <main.add1>
   0x00000000000020e8 <+24>: jmp    0x20ea <main.bar+26>
   0x00000000000020ea <+26>: jmp    0x20e1 <main.bar+17>
   0x00000000000020ec <+28>: callq  0x493c0 <runtime.morestack_noctxt>
   0x00000000000020f1 <+33>: jmp    0x20d0 <main.bar>



在 2017年9月4日星期一 UTC+8下午3:54:13,John Souvestre写道:
Reply all
Reply to author
Forward
0 new messages