Search code examples
godeadlock

Unable to find reason for go deadlock


Unable to find a reason as to why this code deadlocks. The aim here is make the worker go routines do some work only after they are signaled.

If the signalStream channel is removed from the code, it works fine. But when this is introduced, it deadlocks. Not sure the reason for this. Also if there are any tools to explain the occurrence of deadlock, it would help.

package main

import (
    "log"
    "sync"
)

const jobs = 10
const workers = 5

var wg sync.WaitGroup

func main() {

    // create channel
    dataStream := make(chan interface{})
    signalStream := make(chan interface{})

    // Generate workers

    for i := 1; i <= workers; i++ {
        wg.Add(1)
        go worker(dataStream, signalStream, i*100)
    }

    // Generate jobs

    for i := 1; i <= jobs; i++ {
        dataStream <- i
    }
    close(dataStream)

    // start consuming data
    close(signalStream)

    wg.Wait()

}

func worker(c <-chan interface{}, s <-chan interface{}, id int) {
    defer wg.Done()
    <-s

    for i := range c {
        log.Printf("routine - %d - %d \n", id, i)
    }

}

Solution

  • Generate the jobs in a separate gorouine, i.e. put the whole jobs loop into a goroutine. If you don't then dataStream <- i will block and your program will never "start consuming data"

    // Generate jobs
    go func() {
        for i := 1; i <= jobs; i++ {
            dataStream <- i
        }
        close(dataStream)
    }()
    

    https://go.dev/play/p/ChlbsJlgwdE