我知道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)
}
答案 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)
}