0{"/> 0{">

Home  >  Article  >  Backend Development  >  Fatal error: all goroutines are sleeping - deadlock! Error execution

Fatal error: all goroutines are sleeping - deadlock! Error execution

王林
王林forward
2024-02-10 16:42:19999browse

致命错误:所有 goroutine 都在睡觉 - 死锁!错误执行

#php editor Strawberry will introduce you to a common programming error in this article: Fatal error: "All goroutines are sleeping - deadlock! Error execution". This is one of the common mistakes in the Go language and one of the challenges that developers often encounter. In this article, we will explain the cause and solution of this error in detail to help everyone better understand and deal with this problem. Whether you are a beginner or an experienced developer, you will get valuable information and tips from this article. Let’s explore together!

Question content

I am very new to concurrency in go, so I tried an example with channels and goroutines. I want the producer-consumer model. The producer function always gives random strings and the consumer modifies them by making them uppercase. I want to run it for a limited time (2 seconds).

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

I only receive one array element and some errors. What changes need to be made to make this example work?

Output:

two

Fatal error: All goroutines are sleeping - deadlock!

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

Coroutine 6 [chan send]: main.producer({0xc00004e040, 0x4, 0x0?}, 0x0?) Created by main. main Exit Status 2

Solution

Your consumer should run in a loop, this has already been mentioned.

Change the first parameter of consumer so that it is chan string instead of a string. This way the producer can keep writing to this channel for the consumer to publish on another channel until the time limit expires.

func consumer(consumechan chan string, outch chan string) {
    for {
        select {
        case s := <- consumechan:
            s = strings.toupper(s)
            outch <- s
        }
    }
}

Now, in the main function before calling go consumer(), you are waiting for the first response from the producer on the c1 channel. Don't do this, instead pass the c1 channel as the first argument.

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
        case response := <- d1:
            fmt.Println(response)
            time.Sleep(50 * time.Millisecond)
        }
    }
}

This should show the producer continuously writing random numbers on the c1 channel, and the consumer continuously writing all uppercase text on the d1 channel until the 2 seconds are up.

The above is the detailed content of Fatal error: all goroutines are sleeping - deadlock! Error execution. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete