Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Not getting any output even if there is no race conditions

I am trying to create producer-consumer message queue system in Golang using buffered channel. Here is my implementation.

package main

import "fmt"

type MessageQueue struct {
    storage chan int
    count   int
}

var done = make(chan bool)

func NewMessageQueue(count int) *MessageQueue {
    ret := &MessageQueue{
        count:   count,
        storage: make(chan int, count),
    }
    return ret
}

func (m *MessageQueue) Produce() {
    for i := 0; i < m.count; i++ {
        m.storage <- i + 1
    }
    done <- true
}

func (m *MessageQueue) Consume(f func(int) int) {
    for each := range m.storage {
        fmt.Printf("%d ", f(each))
    }
}

func main() {
    op1 := func(a int) int {
        return a * a
    }
    msq := NewMessageQueue(10)
    go msq.Produce()
    go msq.Consume(op1)
    <-done
}

But unfortunately, I am not able to get the output when I run go run main.go however to check if there is any race condition or not, when I try go run -race main.go, I do get the output. I am unable to understand why it is happening. Can anyone help me here?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

When your producer can send the values, it sends a value on the done channel so your app can terminate immediately.

Instead when the producer is done, it should close the m.storage channel, signalling no more values will be sent, and do not send a value on done, as you’re not done!

You’re done when values are consumed, so send a value on done in Consume():

func (m *MessageQueue) Produce() {
    for i := 0; i < m.count; i++ {
        m.storage <- i + 1
    }
    close(m.storage)
}

func (m *MessageQueue) Consume(f func(int) int) {
    for each := range m.storage {
        fmt.Printf("%d ", f(each))
    }
    done <- true
}

This will output (try it on the Go Playground):

1 4 9 16 25 36 49 64 81 100 
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading