I have a base channel to which I input a number This later on modifies itself by a formula There are 3 channels which can receive the value subject to different cases The average of the sent numbers has to be between two values as seen in the if loop
if average < 10 {
channel <- average
}
if average > 0 && average < 100 {
channel1 <- average
}
if average > 75 && average < 200 {
channel2 <- average
}
The problem that I am facing is while avoiding a deadlock situation I have to do a strange if cycle, which reads all the values which were sent, but never read
This happens because the averageisOK global value becomes false, but atleast 2 values are still waiting to be read or maybe that's how I understand it.
So is it possible to avoid the strange cycles and have a better solution to this.
package main
import(
"fmt"
"sync"
)
var wait sync.WaitGroup
var averageIsOk = true
var doneSendersCount = 0
var counterIsDone = false
func main() {
counterChannel := make(chan float64)
channel := make(chan float64)
channel1 := make(chan float64)
channel2 := make(chan float64)
for i := 0; i < 10; i++ {
wait.Add(1)
go send(counterChannel, float64(i))
}
wait.Add(1)
go count(counterChannel, channel, channel1, channel2)
wait.Add(1)
go print(channel, 1)
wait.Add(1)
go print(channel1, 2)
wait.Add(1)
go print(channel2, 3)
wait.Wait()
}
func send (counterChannel chan<- float64, startNumber float64){
defer wait.Done()
i := startNumber
for averageIsOk {
counterChannel <- i
i = i * i - 4 * i + 1
}
doneSendersCount++
}
func count (counterChannel <-chan float64, channel chan<- float64, channel1 chan<- float64, channel2 chan<- float64){
defer wait.Done()
var averageArray [15]float64
for i := 0; i < 15; i++ {
averageArray[i] = 0
}
for averageIsOk {
receivedNumber := <- counterChannel
for i := 14; i > 0; i-- {
averageArray[i] = averageArray[i - 1]
}
averageArray[0] = receivedNumber
average := 0.0
for i := 0; i < 15; i++ {
average += averageArray[i]
}
average = average / 15
if average < 10 {
channel <- average
}
if average > 0 && average < 100 {
channel1 <- average
}
if average > 75 && average < 200 {
channel2 <- average
}
if average > 200 {
close(channel)
close(channel1)
close(channel2)
averageIsOk = false
}
}
counterIsDone = true
for doneSendersCount != 10 {
select {
case <- counterChannel:
break
default:
break
}
}
}
func print (printChannel <-chan float64, printerNumber int){
defer wait.Done()
for averageIsOk {
receivedNumber := <- printChannel
fmt.Println("Kanalas nr-", printerNumber, ":", receivedNumber)
}
for !counterIsDone {
select {
case <- printChannel:
break
default:
break
}
}
}