修复主要功能上的通道错误,但如果在goroutine中修改了progrenn则没有错误

时间:2018-01-31 06:31:08

标签: go

我通过goroutine将数据发送到频道。当我想在主要功能中重新获取它时,在频道的最后收到时会出现死锁,

package main
import (
    "time"
    "fmt"
)

func sender(ch chan string) {
    ch<-"chenl"
    ch<-"zhangs"
    ch<-"lisi"
}

func geter(ch chan string){
    for{
        var result string
        result = <- ch
        fmt.Println("print result %s",result)
    }
}


func main() {
    ch :=make(chan  string)
    //var result string
    go sender(ch)
    for{
        var result string
        result = <- ch
        fmt.Println("print result %s",result)
    }
    time.Sleep(10*time.Second)
}

输出:

print result %s chenl
print result %s zhangs
print result %s lisi
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()

但是,如果我也替换了goroutine中的已恢复进度,则没有错误或者有人帮助我,这会发生吗?

package main

import (
    "time"
    "fmt"
)

func sender(ch chan string) {
    ch<-"chenl"
    ch<-"zhangs"
    ch<-"lisi"
}

func geter(ch chan string){
    for{
        var result string
        result = <- ch
        fmt.Println("print result %s",result)
    }
}

func main() {
    ch :=make(chan  string)
    go sender(ch)
    go geter(ch)
    time.Sleep(10*time.Second)
}

输出:

print result %s chenl
print result %s zhangs
print result %s lisi

2 个答案:

答案 0 :(得分:3)

在第一个示例中,您有两个goroutines:maingo sender(ch)

在第三次阅读频道后,main被屏蔽,并且存在死锁:main被屏蔽,go sender(ch)已完成。

在第二个示例中,您有三个goroutine maingo sender(ch)go geter(ch)Sendergetter正在使用频道main正在休眠(没有死锁)。当time.Sleep完成后,main返回,而在Go中,从main返回结束程序,无论其他任何goroutine是否正在运行。

答案 1 :(得分:1)

func sender(ch chan string) {
    ch<-"chenl"
    ch<-"zhangs"
    ch<-"lisi"
    close(ch)
}

问题是,当您完成更多值并且for循环永远不会结束时,您不会关闭频道。

您应该调整通道的范围,并且在通道关闭时循环将结束。

for result := range ch {
    fmt.Printf("print result %s\n",result)
}