使用通道时出现问题:所有goroutine都处于休眠状态-死锁

使用通道时出现问题:所有goroutine都处于休眠状态-死锁,go,channels,Go,Channels,我试图了解渠道是如何运作的。我举了一个例子: import ( "fmt" "runtime" "time" ) func greet(c chan string) { fmt.Println("1: " + <-c) fmt.Println("2: " + <-c) } func main() { fmt.Println("

我试图了解渠道是如何运作的。我举了一个例子:

import (
    "fmt"
    "runtime"
    "time"
)

func greet(c chan string) {
    fmt.Println("1: " + <-c)
    fmt.Println("2: " + <-c)
}

func main() {
    fmt.Println("main() started")

    c := make(chan string, 1)

    go greet(c)
    c <- "John"

    c <- "Mike"
    c <- "Mary"
    fmt.Println("active goroutines", runtime.NumGoroutine())
    c <- "Edward"
    time.Sleep(time.Second)
    fmt.Println("main() stopped")
}
导入(
“fmt”
“运行时”
“时间”
)
func问候语(c chan string){

fmt.Println(“1:”+参考以下代码,以便您更好地理解。我也添加了注释。虽然@mkopriva消除了您的疑虑,但我认为如果我发布注释代码会更好

主程序包
进口(
“fmt”
“时间”
)
func问候语(c chan string){
//在调用close()之前在通道上的范围
对于r:=范围c{
//打印姓名
fmt.Println(右)
}
}
func main(){
fmt.Println(“main()已启动”)
c:=make(chan string,1)//制作一个容量为1的缓冲通道
去迎接(c)//生成goroutine

你问题的答案很简单。 如果你在频道里放东西,你必须设法把它拿出来。 函数
greet(c chan string)
在前面放一个“go”时不会无限运行。它只是意味着函数正在调用一个新的go例程来运行。 您编写的代码会产生死锁,因为函数在跨越通道后被终止

c <- "Edward"
go greet(c)
c <- "John"
c <- "Mike"
//all these things happen at the same time

在操场上运行此代码表明您的理解是正确的。您的代码只打印John和Mike,因为您的goroutine只有两个打印语句,每个语句都有一个通道receive。为什么您希望它打印更多内容?此外,您可以发送Mary而不会使程序崩溃,因为您使用的是缓冲通道大小为1,您不能再发送Edward,因为没有更多的代码可以首先接收Mary,如果您将大小更改为2,则您也可以发送Edward,而无需添加接收,并且您的程序不会崩溃,但是Mary和Edward仍然不会被打印,因为您还没有编写任何代码来执行此操作。@mkopriva这就是m一旦greet()函数中的所有代码完全执行,它将停止运行?是的,就像任何其他函数一样。关键字
go
并不意味着“无限期运行此函数”如果你是这么想的。@sonal,你能把解决方案标记为已接受吗?否则,问题将保留在未回答部分。这只会帮助社区快速找到相关答案。
func greet(c chan string) {
    for name := range c {
        fmt.Println(name)
    }
}