代码之家  ›  专栏  ›  技术社区  ›  Charlie Parker

以下围棋代码中是否存在死锁?但未输出

  •  0
  • Charlie Parker  · 技术社区  · 11 年前

    我正在运行以下内容 go code 并且不产生输出:

    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)")
    }
    

    是否存在僵局?这个 Print(c) 函数甚至没有被调用。。。?我觉得很奇怪。 在围棋运动场中,它的链接是: http://play.golang.org/p/tDjEJKwkRJ

    2 回复  |  直到 11 年前
        1
  •  2
  •   rvignacio    11 年前

    没有错误,在goroutine中调用了Print()函数,但主程序正在退出。。。因此goroutine被终止。

    阅读本演讲: Go Concurrency Patterns (或更好, view it's video ),以了解频道和goroutine的工作原理。

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

        2
  •  2
  •   peterSO    11 年前

    main 函数调用返回,程序退出。它不等待其他(非- 主要的 )要完成的goroutines。

    致电您的 Wait 函数之后 go Print(c) 陈述例如

    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)")
    }
    

    输出:

    Before go Print(c)
    Running Print go-routine
    len(c):  4
    0
    len(c):  3
    1
    len(c):  2
    2
    len(c):  1
    3
    len(c):  0
    After go Print(c)
    

    The Go Programming Language Specification

    Program execution

    一个完整的程序是通过链接一个单一的、未经修改的包来创建的 称为主包及其导入的所有包, 过渡。主包必须具有包名main和声明 不接受参数且不返回值的函数main。

    func main() { … }
    

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