致命错误:所有 goroutines 都睡着了——死锁!错误GO

我是 Go 并发的新手,所以我尝试了一个带有通道和 goroutines 的例子。我想要生产者消费者模式。生产者函数永远提供随机字符串,消费者通过将它们变成大写来修改它们。我想在有限的时间内(2 秒)运行它。


package main


import (

    "fmt"

    "math/rand"

    "strings"

    "time"

)


func producer(x []string, c chan string) {

    i := 1

    for i > 0 {

        randomIndex := rand.Intn(len(x))

        pick := x[randomIndex]

        c <- pick

    }

}


func consumer(x string, c chan string) {

    x1 := strings.ToUpper(x)

    c <- x1

}


func main() {


    s := []string{"one", "two", "three", "four"}

    c1 := make(chan string)

    d1 := make(chan string)

    go producer(s, c1)

    go consumer(<-c1, d1)


    stop := time.After(2000 * time.Millisecond)

    for {

        select {

        case <-stop:

            fmt.Println("STOP AFTER 2 SEC!")

            return

        default:

            fmt.Println(<-d1)

            time.Sleep(50 * time.Millisecond)

        }

    }

}

我只得到一个数组元素和一些错误。需要进行哪些更改才能使此示例有效?


输出:



致命错误:所有 goroutines 都睡着了——死锁!


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


goroutine 6 [chan send]: main.producer({0xc00004e040, 0x4, 0x0?}, 0x0?) 由 main 创建。主要退出状态 2


慕桂英3389331
浏览 95回答 1
1回答

幕布斯7119047

您的消费者应该循环运行,这已经提到过。更改消费者的第一个参数,使其为 achan string而不是字符串。这样生产者就可以不断地写入这个通道,让消费者在另一个通道上发布,直到时间限制到期。func consumer(consumeChan chan string, outCh chan string) {&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case s := <- consumeChan:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s = strings.ToUpper(s)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; outCh <- s&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}现在在go consumer()调用之前的 main func 中,您正在等待c1生产者对频道的第一个响应。c1而不是将通道作为第一个参数传递。func main() {&nbsp; &nbsp; s := []string{"one", "two", "three", "four"}&nbsp; &nbsp; c1 := make(chan string)&nbsp; &nbsp; d1 := make(chan string)&nbsp; &nbsp; go producer(s, c1)&nbsp; &nbsp; go consumer(c1, d1)&nbsp; &nbsp; stop := time.After(2000 * time.Millisecond)&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-stop:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("STOP AFTER 2 SEC!")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; case response := <- d1:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(response)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(50 * time.Millisecond)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}这应该向您展示生产者在通道上连续写入随机数c1,以及消费者在 d1 通道上连续写入所有大写文本,直到 2 秒结束。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go