猿问

为什么我有一个死锁,即使它包含一个无限循环?

我开始和 Go 混在一起,我对 go routines 很着迷。我现在写了一个简单的测试,看看我是否可以在连续打印变量的同时更改它的值。


我现在有以下代码:


package main


import (

    "fmt"

    "time"

)


func change(c chan float64) float64 {

    time.Sleep(2 * time.Second)

    return 2.5

}


func main() {


    s := 1.1


    c := make(chan float64)

    go change(c)

    s = <-c


    for {

        fmt.Println(s)

        time.Sleep(100 * time.Millisecond)

    }    

}

不幸的是它以错误结束:


fatal error: all goroutines are asleep - deadlock!


goroutine 1 [chan receive]:

main.main()

        /home/kramer65/repos/go/src/messing_around/main.go:19 +0x7d

exit status 2

我四处搜索,发现当 main 函数结束而 goroutines 还没有结束时,就会发生这种死锁。但是由于我有一个无限循环,我不知道我的代码还有什么问题。


这段代码有什么问题,我如何在不断打印变量的同时更改它的值?


牛魔王的故事
浏览 124回答 1
1回答

天涯尽头无女友

看起来你可能对频道和套路有误解。该行:go change(c)似乎表明该函数change将写入c. 然而,它最终只是在一段时间后返回一个值。此值 ( 2.5) 不会在任何地方收到。此外,c不会被写入任何地方。我怀疑您打算将其2.5写入频道c。其语法如下:c<-2.5因此,如果您将change函数更改为:func change(c chan float64) {&nbsp; &nbsp; time.Sleep(2 * time.Second)&nbsp; &nbsp; c <- 2.5}你不应该再看到死锁了。请注意,我不再返回 afloat64了。我做了一个游乐场来确保这一点:https ://play.golang.org/p/SgLiUmPpcAZ更新评论将1.1始终被通道的值覆盖。但是,如果您想打印 prints的初始值(如评论中所述),则必须稍微更改流程并使用语句select:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "time")func change(c chan float64) {&nbsp; &nbsp; time.Sleep(2 * time.Second)&nbsp; &nbsp; c <- 2.5}func main() {&nbsp; &nbsp; s := 1.1&nbsp; &nbsp; c := make(chan float64)&nbsp; &nbsp; go change(c)&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case s = <-c:&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // c isn't ready yet&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(s)&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(100 * time.Millisecond)&nbsp; &nbsp; }}现在您有了一个select语句,您也可以将它与 atime.Ticker一起使用:ticker := time.NewTicker(100 * time.Millisecond)for {&nbsp; &nbsp; select {&nbsp; &nbsp; case s = <-c:&nbsp; &nbsp; case <-ticker.C:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(s)&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; // c isn't ready yet&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Go
我要回答