Search code examples
functiongogoroutine

What happens to return value from goroutine


Could someone please give clarification values returned from the goroutine. Does the returned value from the goroutine is getting stored on stake.

example :

// function getNumber returns the "int i" and we can't use this returned value
// because this function is invoked as goroutine.
// We know that, to communicate between main and goroutine one could
// use the channel ( chan <- i), but I am interested to know about
// the use of return i in goroutine. Is it possible to get/ use this 
// returned value.
func getNumber(i int) int {
    return i   
    }

func main() {

    for i:=0; i<10; i++ {
        go printNumber(i)
        }
    time.Sleep(5)
    }

Should we try to avoid the return valued in go routine ?


Solution

  • A quick bit of looking at the assembly output shows

    $ go build -gcflags -S z.go
    

    The getNumber() function does store its results to the stack

    "".getNumber t=1 size=16 value=0 args=0x10 locals=0x0
        0x0000 00000 (z.go:5)   TEXT    "".getNumber+0(SB),4,$0-16
        0x0000 00000 (z.go:6)   MOVQ    "".i+8(FP),BX
        0x0005 00005 (z.go:6)   MOVQ    BX,"".~r1+16(FP)
        0x000a 00010 (z.go:6)   RET ,
    

    So when it is called from a goroutine, it does store its results to the stack. However this is a new stack which is destroyed when the goroutine ends so there is no possibility of retrieving the return value.

    "".main t=1 size=96 value=0 args=0x0 locals=0x18
        0x0000 00000 (z.go:9)   TEXT    "".main+0(SB),$24-0
        0x0000 00000 (z.go:9)   MOVQ    (TLS),CX
        0x0009 00009 (z.go:9)   CMPQ    SP,16(CX)
        0x000d 00013 (z.go:9)   JHI ,22
        0x000f 00015 (z.go:9)   CALL    ,runtime.morestack_noctxt(SB)
        0x0014 00020 (z.go:9)   JMP ,0
        0x0016 00022 (z.go:9)   SUBQ    $24,SP
        0x001a 00026 (z.go:10)  MOVQ    $0,AX
        0x001c 00028 (z.go:10)  CMPQ    AX,$10
        0x0020 00032 (z.go:10)  JGE $0,74
        0x0022 00034 (z.go:11)  MOVQ    AX,"".i+16(SP)
        0x0027 00039 (z.go:11)  MOVQ    AX,(SP)
        0x002b 00043 (z.go:11)  MOVQ    $"".getNumber·f+0(SB),CX
        0x0032 00050 (z.go:11)  PUSHQ   CX,
        0x0033 00051 (z.go:11)  PUSHQ   $16,
        0x0035 00053 (z.go:11)  PCDATA  $0,$0
        0x0035 00053 (z.go:11)  CALL    ,runtime.newproc(SB)
        0x003a 00058 (z.go:11)  POPQ    ,CX
        0x003b 00059 (z.go:11)  POPQ    ,CX
        0x003c 00060 (z.go:10)  MOVQ    "".i+16(SP),AX
        0x0041 00065 (z.go:10)  INCQ    ,AX
        0x0044 00068 (z.go:10)  NOP ,
        0x0044 00068 (z.go:10)  CMPQ    AX,$10
        0x0048 00072 (z.go:10)  JLT $0,34
        0x004a 00074 (z.go:13)  MOVQ    $5,(SP)
        0x0052 00082 (z.go:13)  PCDATA  $0,$0
        0x0052 00082 (z.go:13)  CALL    ,time.Sleep(SB)
        0x0057 00087 (z.go:14)  ADDQ    $24,SP
        0x005b 00091 (z.go:14)  RET ,
    

    However there is no way of retrieving these results.