Concurrency 以下go代码中是否存在死锁?但不是输出

Concurrency 以下go代码中是否存在死锁?但不是输出,concurrency,go,Concurrency,Go,我正在运行以下程序,但它不会产生输出: package main import "fmt" //import "strconv" import "time" func Wait(){ time.Sleep(2000 * time.Millisecond) } func Print(c chan string){ fmt.Println("Running Print go-routine") for{ fmt.Println("len(c): ", l

我正在运行以下程序,但它不会产生输出:

package main

import "fmt"
//import "strconv"
import "time"

func Wait(){
    time.Sleep(2000 * time.Millisecond)
}

func Print(c chan string){
    fmt.Println("Running Print go-routine")
    for{
        fmt.Println("len(c): ", len(c))
        str := <- c
        fmt.Println(str)
    }
}

func main() {
    c := make(chan string, 4)
    c <- "0"
    c <- "1"
    c <- "2"
    c <- "3"
    Wait()
    fmt.Println("Before go Print(c)")
    go Print(c)
    fmt.Println("After go Print(c)")
}
主程序包
输入“fmt”
//导入“strconv”
导入“时间”
func Wait(){
时间。睡眠(2000*时间。毫秒)
}
func打印(c chan字符串){
fmt.Println(“运行打印开始程序”)
为了{
fmt.Println(“第(三)节:”,第(三)节)

str:=没有错误,在goroutine中调用Print()函数,但主程序在此之后立即退出…因此goroutine被终止

阅读本演讲:(或者更好),了解频道和Goroutine是如何工作的


请记住,当主函数返回时,程序将完成。

没有错误,Print()函数在goroutine中调用,但主程序将在该函数返回后立即退出…因此goroutine将终止

阅读本演讲:(或者更好),了解频道和Goroutine是如何工作的


请记住,当主函数返回时,程序将完成。

main
函数调用返回时,程序将退出。它不会等待其他(非
main
)goroutine完成

稍后在执行
go Print(c)
语句后调用
Wait
函数。例如

package main

import (
    "fmt"
    "time"
)

func Wait() {
    time.Sleep(2000 * time.Millisecond)
}

func Print(c chan string) {
    fmt.Println("Running Print go-routine")
    for {
        fmt.Println("len(c): ", len(c))
        str := <-c
        fmt.Println(str)
    }
}

func main() {
    c := make(chan string, 4)
    c <- "0"
    c <- "1"
    c <- "2"
    c <- "3"
    fmt.Println("Before go Print(c)")
    go Print(c)
    Wait()
    fmt.Println("After go Print(c)")
}

一个完整的程序是通过链接一个单独的、未导入的包来创建的 调用主包及其导入的所有包, 可传递。主包必须具有包名main和declare 不带参数也不返回值的函数main

func main() { … }
程序执行从初始化主包开始,然后 调用函数main。当该函数调用返回时 程序退出。它不会等待其他(非主)goroutine退出 完成


main
函数调用返回时,程序退出。它不会等待其他(非
main
)goroutine完成

稍后在执行
go Print(c)
语句后调用
Wait
函数。例如

package main

import (
    "fmt"
    "time"
)

func Wait() {
    time.Sleep(2000 * time.Millisecond)
}

func Print(c chan string) {
    fmt.Println("Running Print go-routine")
    for {
        fmt.Println("len(c): ", len(c))
        str := <-c
        fmt.Println(str)
    }
}

func main() {
    c := make(chan string, 4)
    c <- "0"
    c <- "1"
    c <- "2"
    c <- "3"
    fmt.Println("Before go Print(c)")
    go Print(c)
    Wait()
    fmt.Println("After go Print(c)")
}

一个完整的程序是通过链接一个单独的、未导入的包来创建的 调用主包及其导入的所有包, 可传递。主包必须具有包名main和declare 不带参数也不返回值的函数main

func main() { … }
程序执行从初始化主包开始,然后 调用函数main。当该函数调用返回时 程序退出。它不会等待其他(非主)goroutine退出 完成


始终使用
go run-race
测试此类代码。在打印有机会打印任何内容之前,您的程序将退出。始终使用
go run-race
测试此类代码。在打印有机会打印任何内容之前,您的程序将退出。请记住,如果这是一个真正的程序,
Print
将永远等待,因为永远不要关闭频道或发出信号让它停止尝试读取。@OneOfOne:
Print
不会永远等待。当
main
终止时,它将被杀死。我知道,我说了“如果这是一个真正的程序”。@OneOfOne:你说的“真正的程序”是什么意思?一个运行
go Print()的程序
并且不会立即退出,例如每次启动它的http处理程序,这将是一个内存泄漏,因为它永远不会退出。请记住,如果这是一个真正的程序,
Print
将永远等待,因为您从未关闭通道或发出信号让它停止尝试读取。@one:
Print
不会等待很久r、 当
main
终止时,它将被杀死。我知道,我说过“如果这是一个真正的程序”。@OneOfOne:你说的“真正的程序”是什么意思?一个运行
go Print()
并且不会立即退出的程序,例如每次启动它的http处理程序,这将是一个内存泄漏,因为它永远不会退出。