如何确定goroutine的堆栈大小?

问题描述 投票:2回答:2

我知道go例程可以执行一些阻塞操作,想知道goroutine是否可以像常规函数一样调用用户定义的阻塞函数。用户定义的阻止功能具有几个步骤,如step1,step2。

换句话说,我想找出我们是否可以在go例程中嵌套嵌套的阻塞调用。

UPDATE

最初的目的是找到goroutine使用的堆栈大小,特别是对于嵌套的阻塞调用。对困惑感到抱歉。多亏了答案和评论,我创建了以下具有100,000个goroutine的函数,在我的Ubuntu桌面上占用了782MB的虚拟内存和416MB的常驻内存。每个go例程堆栈平均需要78KB的内存。这是正确的说法吗?

package main

import (
    "fmt"
    "time"
)

func f(a int) {
    x := f1(a);
    f2(x);
}
func f1(a int) int {
    r := step("1a", a);
    r = step("1b", r);
    return 1000 * a;
}
func f2(a int) {
    r := step("2a", a);
    r = step("2b", r);
}
func step(a string, b int) int{
    fmt.Printf("%s %d\n", a, b);
    time.Sleep(1000 * time.Second)
    return 10 * b;
}

func main() {
    for i := 0; i < 100000; i++ {
        go f(i);
    }
    //go f(20);
    time.Sleep(1000 * time.Second)
}
go goroutine
2个回答
3
投票

我相信您是对的,尽管我不确定“虚拟”和“常驻”内存之间的关系,但可能存在一些重叠。

要考虑的一些事情:您正在运行100,000,而不是10,000。

堆栈本身可能包含用于printfs的字符串,方法参数等。

从go 1.2开始,默认堆栈大小(每个go例程)为8KB,这也许可以解释其中的某些内容。

从1.3版开始,它还使用exponentially increasing堆栈大小,但是我怀疑那是您遇到的问题。


0
投票

答案是肯定的。

goroutine是一个“轻量级线程”,这意味着它可以独立于程序中的其他代码执行操作。就像启动一个新程序一样,但是您可以使用golang提供的结构(通道,锁等)与其他代码进行通信。

P.S。一旦main函数结束,所有goroutine都会被杀死(这就是为什么您需要time.Sleep()的原因)

这是一个简单的示例(由于其限制,它不会在golang游乐场中运行:

package main

import (
    "fmt"
    "time"
)

func saySomething(a, b func()){
  a()
  b()
}

func foo() {
  fmt.Println("foo")
}

func bar() {
  fmt.Println("bar")
}

func talkForAWhile() {
  for {
  saySomething(foo, bar)
  }
}

func main() {
  go talkForAWhile()
  time.Sleep(1 * time.Second)
}
© www.soinside.com 2019 - 2024. All rights reserved.