当前位置: 首页 > 面试题库 >

从goroutine返回值会发生什么

吴德辉
2023-03-14
问题内容

有人可以提供goroutine返回的澄清值。从goroutine返回的值是否已存入抵押。

例如:

// 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)
    }

我们是否应该避免在go例程中避免返回值?


问题答案:

快速查看一下组装输出显示

$ go build -gcflags -S z.go

getNumber()函数确实将其结果存储到堆栈中

"".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 ,

因此,当从goroutine调用它时,它会将结果存储到堆栈中。但是,这是一个新的堆栈,当goroutine结束时,该堆栈会被破坏,因此无法获取返回值。

"".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 ,

但是,无法检索这些结果。



 类似资料:
  • 问题内容: 以下代码给出了编译错误,提示“意外运行”: 我知道,如果正常调用函数就可以获取返回值,而无需使用goroutine。或者我可以使用频道等 我的问题是为什么不能从goroutine中获取像这样的返回值。 问题答案: 严格的答案是您 可以 做到。这可能不是一个好主意。下面的代码可以做到这一点: 这将产生一个新的goroutine,它将进行计算,然后将结果分配给。问题是:您将如何使用原始go

  • 我对反应性API比较陌生,很好奇当我们从web控制器返回流量时,幕后发生了什么。 根据spring-web文档 反应性返回值的处理如下: 与使用DeferreDreSult类似,适用于单值promise。例子包括单(反应器)或单(RxJava)。 因此,例外是两个API的行为应该与多值流(Flux)的行为应该与返回deferredresult的行为相似。 但是在返回延迟结果的API中,整个列表在浏

  • 问题内容: 我创建了一个从API获取URL并返回URL字符串作为结果的函数。但是,Xcode给我此错误消息: void函数中非预期的非无效返回值 有谁知道为什么会这样吗? 问题答案: 使用闭包而不是返回值:

  • 问题内容: 我试图说服自己,该子句中采取的操作在函数返回 之前发生 (从内存一致性的角度来看)。从JVM规范,很显然,在一个线程中,程序顺序应该是驱动 之前发生 关系-如果 一个 发生 b 按照程序顺序,然后 一 前发生 b 。 但是,我没有看到任何明确说明最终 会在 返回 之前发生的 东西,是吗?或者,编译器是否可以通过某种方式对子句进行重新排序,因为它只是在记录日志。 激励示例:我有一个线程从

  • 问题内容: 我在Go中有一个返回两个值的函数。我想将其作为goroutine运行,但是我无法弄清楚创建接收两个值的通道的语法。有人能指出我正确的方向吗? 问题答案: 使用两个值的字段定义自定义类型,然后创建该类型的。 编辑:我还添加了一个使用多个通道而不是自定义类型的示例(在底部)。我不确定哪个更惯用。 例如: 然后 使用自定义类型的频道(Playground)的示例: 产生: LOREM,5 I

  • hashcode或hashmap是如何工作的,如果我们重写hashcode返回的总是常量,而重写的equals方法返回false,它如何能够在返回或删除时识别准确的对象?时间bean忘记了性能所有的东西,我的问题是它如何能够识别精确的对象,让我再解释一点,我有一个有两个字段的person类,已经重写了返回总是1的hashcode和重写了返回false的equals方法,已经创建了3个对象,对象1-