Home > Blockchain >  Channel not receiving any values if sending to many values
Channel not receiving any values if sending to many values

Time:08-20

If I pass more than 12 for totalValues to getResults(), no values are read from channel resultCh and I get fatal error: all goroutines are asleep - deadlock!:

package main

type result struct {
    index int
    count int
}

func getResults(indexCh chan int, resultCh chan result, totalValues int) {
    allFields := make([]int, totalValues)

    for i := range allFields {
        indexCh <- i
        println("Sent value", i)
    }

    println("Sent all values")

    for i := 0; i < totalValues; i   {
        value := <-resultCh
        println("Received result", value.index)

        allFields[value.index] = value.count
    }

    println("Done processing")
}

func processValue(indexCh chan int, ch chan result) {
    for index := range indexCh {
        println("Received value", index)

        ch <- result{
            index: index,
            count: index * index,
        }

        println("Sent result", index)
    }
}

func main() {
    bufferDepth := 4
    indexCh := make(chan int, bufferDepth)
    resultCh := make(chan result, bufferDepth)

    for i := 0; i < 4; i   {
        go processValue(indexCh, resultCh)
    }

    // Value > 12 results in goroutine asleep
    getResults(indexCh, resultCh, 12)
}

The above code works by launching four goroutines using function processValue() that read values from buffered channel indexCh. Integers 0 to totalValues are inserted into indexCh by getResults(). processValue() processes the value and puts the result onto buffered channel resultCh, which is read by a getResults().

I only only observe this problem when totalValues is greater than 12. No values are read from resultCh because "Received result..." is not printed.

If I increase bufferDepth to five, the program completes successfully for totalValues > 12 and < 15.

The program also completes successfully if the buffer depth of resultCh matches totalValues.

CodePudding user response:

getResults starts by writing all values to the channel. There are 4 goroutines listening, so each picks up those values, and they are blocked writing to the result channel. Channels have buffer sizes of 4. So 4 goroutines each can write a total of 4 values to result channel before blocking.

4 goroutines 4 index channel size 4 result channel size = 12 entries

After that, the processValue is blocked at writing to the channel, because getResults are also blocked writing to the indexCh.

  • Related