3 回答
TA贡献1784条经验 获得超9个赞
您只是遇到了时间问题,因为您没有“协调”您的 go 例程。处理这个问题的常用方法是使用守卫。我不时看到使用频道和阻塞选择的另一个选项。等待守卫的实现看起来像这样;
func main() {
wg := sync.WaitGroup{}
wg.Add(1)
go say("world") // create a new goroutine
wg.Add(1)
say("hello") // current goroutine
wg.Wait()
}
虽然通道选项(在这个例子中实际上并不有趣或有用)更像是这样的;
func main() {
done := make(chan bool)
go say("world", done) // create a new goroutine
say("hello", done) // current goroutine
select {
case fin := <- done:
//on finished
return
}
}
func say(s string, chan bool) {
for i := 0; i < 5; i++ {
fmt.Println(s)
}
done <- true
}
但是,在上面的示例中,第一个调用完成将允许程序完成执行。为了确保两者都完成,您必须将不同的通道传递给每个通道,并对两者进行阻塞读取。当你的 goroutine 正在做真正的工作并且你想要从它们中聚合数据或者需要更复杂的协调(比如根据以前的结果产生新的 goroutines 等)时,这更像是我会使用的一种模式。
TA贡献1784条经验 获得超2个赞
您不允许 goroutine 在main()退出之前运行。
即使第二次调用say块(简短地),也不能保证第一个 goroutine 可以运行。您需要等待两者都返回,这通常是通过 WaitGroup 完成的
var wg sync.WaitGroup
func say(s string) {
defer wg.Done()
for i := 0; i < 5; i++ {
//runtime.Gosched()
fmt.Println(s)
}
}
func main() {
wg.Add(1)
go say("world") // create a new goroutine
wg.Add(1)
say("hello") // current goroutine
wg.Wait()
}
TA贡献1833条经验 获得超4个赞
这是因为主要的 goroutine 退出得太早了。当主 goroutine 退出时,进程将退出,因此其他 goroutine 没有机会运行。如果您希望 goroutines 运行,请保持主程序运行足够长的时间。
package main
import (
"fmt"
"runtime"
)
func say(s string) {
for i := 0; i < 5; i++ {
fmt.Println(s)
}
}
func main() {
go say("world") // create a new goroutine
runtime.Gosched()
say("hello") // current goroutine
time.Sleep(1 * time.Second) // this line
}
- 3 回答
- 0 关注
- 147 浏览
添加回答
举报