【问题标题】:How to identify the stack size of goroutine?如何识别 goroutine 的堆栈大小?
【发布时间】:2020-03-03 15:38:14
【问题描述】:

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

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

更新

最初的意图是找到 goroutine 使用的堆栈大小,尤其是嵌套阻塞调用。对困惑感到抱歉。感谢答案和 cmets,我在我的 Ubuntu 桌面上创建了以下具有 100,000 个 goroutines 的函数,它占用了 782MB 的虚拟内存和 416MB 的驻留内存。每个 goroutine 堆栈平均有 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)
}

【问题讨论】:

  • 我建议您完成一些基本教程。 goroutine 的全部意义在于异步执行“阻塞”代码。

标签: go goroutine


【解决方案1】:

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

需要考虑的一些事项:您运行 100,000 次,而不是 10,000 次。

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

从 go 1.2 开始,默认堆栈大小(每个 go 例程)是 8KB,这可以解释其中的一些原因。

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

【讨论】:

  • 谢谢@rogerdpack!感谢您指出有 100,000 个围棋例程。现在说得通了。
【解决方案2】:

简短回答是。

goroutine 是一个“轻量级线程”,这意味着它可以独立于程序中的其他代码来做一些事情。这几乎就像您开始了一个新程序一样,但是您可以使用 golang 提供的结构(通道、锁等)与您的其他代码进行通信。

附:一旦 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)
}

【讨论】:

    猜你喜欢
    • 2018-01-26
    • 2014-12-08
    • 1970-01-01
    • 2013-10-06
    • 2013-10-02
    • 2013-12-22
    • 2023-04-10
    • 2011-11-24
    • 1970-01-01
    相关资源
    最近更新 更多