goroutine调用的堆栈大小

时间:2014-08-14 21:25:08

标签: go goroutine

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

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

更新

最初的目的是找到goroutine使用的堆栈大小,尤其是嵌套阻塞调用。对困惑感到抱歉。感谢答案和评论,我创建了以下具有10,000个goroutine的函数,在我的Ubuntu桌面上花了782MB的虚拟内存416MB的Resident内存。它为每个常规堆栈均匀地提供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)
}

2 个答案:

答案 0 :(得分:2)

我相信你是对的,虽然我不确定&#34;虚拟&#34;之间的关系。和#34;常驻&#34;记忆它可能存在一些重叠。

需要考虑的一些事项:您显示的是100,000,而不是10,000。

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

从第1.2步开始,默认堆栈大小(每个例行程序)为8KB,这可以解释其中的一些。

从开始1.3开始,它也使用exponentially increasing堆栈大小,但我怀疑这是你遇到的问题。

答案 1 :(得分:0)

简短回答是的。

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

P.S。一旦主函数结束,所有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)
}