Concurrency 为什么我的并发函数在Go中过早退出?

Concurrency 为什么我的并发函数在Go中过早退出?,concurrency,go,Concurrency,Go,我正在浏览围棋训练营,现在正在阅读围棋并发章节。我以前从未在编程中使用过并发,也不了解该程序的输出: package main import ( "fmt" "time" ) func say(s string) { for i := 0; i < 2; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } } func main() { go say

我正在浏览围棋训练营,现在正在阅读围棋并发章节。我以前从未在编程中使用过并发,也不了解该程序的输出:

package main

import (
    "fmt"
    "time"
)

func say(s string) {
    for i := 0; i < 2; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    go say("world")
    say("hello")
}
有人能解释为什么“世界”不像“你好”那样打印两次吗?也许可以解释一下使用并发的想法


注意,去操场链接

当main返回时,Go程序退出。在这种情况下,您的程序不会在退出之前等待在另一个goroutine中打印最终的“世界”

下面的代码()将确保main从不退出,从而允许另一个goroutine完成

package main

import (
    "fmt"
    "time"
)

func say(s string) {
    for i := 0; i < 2; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    go say("world")
    say("hello")
    select{}
}
主程序包
进口(
“fmt”
“时间”
)
func say(s字符串){
对于i:=0;i<2;i++{
时间。睡眠(100*时间。毫秒)
fmt.Println(s)
}
}
func main(){
去说(“世界”)
说(“你好”)
选择{}
}
正如您可能已经注意到的,这会导致死锁,因为程序无法前进。您可能希望添加一个频道或sync.Waitgroup,以确保程序在另一个goroutine完成后立即干净地退出

例如():


func say(s string,ch chan当main返回时,一个Go程序退出。在这种情况下,您的程序不会等待在退出之前在另一个goroutine中打印最终的“world”

下面的代码()将确保main从不退出,从而允许另一个goroutine完成

package main

import (
    "fmt"
    "time"
)

func say(s string) {
    for i := 0; i < 2; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    go say("world")
    say("hello")
    select{}
}
主程序包
进口(
“fmt”
“时间”
)
func say(s字符串){
对于i:=0;i<2;i++{
时间。睡眠(100*时间。毫秒)
fmt.Println(s)
}
}
func main(){
去说(“世界”)
说(“你好”)
选择{}
}
您可能已经注意到,这会导致死锁,因为程序无法继续。您可能希望添加一个通道或sync.Waitgroup,以确保程序在另一个goroutine完成后立即干净地退出

例如():

func say(s字符串,ch chan
func say(s string, ch chan<- bool) {
    for i := 0; i < 2; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }

    if ch != nil {
        close(ch)
    }
}

func main() {
    ch := make(chan bool)
    go say("world", ch)
    say("hello", nil)
    // wait for a signal that the other goroutine is done
    <-ch
}