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.
package main
import "runtime"
// GOMAXPROCS=1var 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>>>")}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.
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!).
(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 barNo symbol "bar" in current context.(gdb) disas main.barDump 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>