Simple multiple producer and single consumer concurrency pattern Anyone please review and share your feedback for the following code. 
Multiple producers generate random integer numbers and a single consumer receives it to display only odd numbers out of it.

package main

import (
"fmt"
"time"
"math/rand"
"sync"
)

var msgs = make(chan int)
var dummy = make(chan bool)
var wg sync.WaitGroup

func main() {
    defer close(msgs)
    defer close(dummy)
    numberOfProducers := 10
    go func() {
        for i := 0; i &lt; numberOfProducers ; i++ {
            go produce() // Multiple producers
        }
        dummy &lt;- true
    }()
    go consume() // Single consumer go routine
    &lt;- dummy
}

func produce() {
     wg.Add(1)
     msgs &lt;- getRandomIntegerNumber()
}

// Single consumer
func consume () {
    for {
      msg := &lt;-msgs
      if ( msg % 2 != 0) {
         fmt.Printf(" The number %d is odd \n", msg);
      }
      wg.Done()
    }
}

func getRandomIntegerNumber() int {
     rand.Seed(time.Now().UnixNano())
     return rand.Intn(1000)
}
So currently the WaitGroup is not being used to wait for the producing to complete.  This means that it is possible for this programme to run without producing any results as each go produce() is done in it's own go routine so true can be sent immediately to dummy if the main go routine gets all the CPU time thus main exits with nothing being printed.

Personally I would use the WaitGroup to do the waiting and then close the msgs channel to indicate to the consume that it is done and use a further WaitGroup to then indicate to main that consume is done.

In addition to the concurrency parts, I also wouldn't use global variables but instead pass them into the functions that use them.   Putting this together then you get:

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

func main() {
    msgs := make(chan int)

    // Start the consuming go routine before producing so that we can then just wait for the producing
    // to complete on the main go routine rather than having to have a separate go routine to wait to
    // close the channel.
    var consumeWG sync.WaitGroup
    consumeWG.Add(1)
    go consume(msgs, &amp;consumeWG)

    var produceWG sync.WaitGroup
    numberOfProducers := 10
    for i := 0; i &lt; numberOfProducers; i++ {
        produceWG.Add(1)
        go produce(msgs, &amp;produceWG) // Multiple producers
    }

    // Wait for producing to complete then tell the consumer by closing the channel.
    produceWG.Wait()
    close(msgs)

    consumeWG.Wait()
}

func produce(msgs chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    msgs &lt;- getRandomIntegerNumber()
}

// Single consumer
func consume(msgs chan int, wg *sync.WaitGroup) {
    // Range of msgs, this will consume all messages in the channel then exit when the channel is closed.
    // This provides communication between the go routines when completion has happened as well as not
    // leaking the consuming go routine as would happen with an forever loop.
    for msg := range msgs {
        if msg%2 != 0 {
            fmt.Printf(" The number %d is odd \n", msg)
        }
    }
    wg.Done()
}

func getRandomIntegerNumber() int {
    rand.Seed(time.Now().UnixNano())
    return rand.Intn(1000)
}