What I am trying to do? I am new to this
I have an array like this
input := []int{20, 2112, 212, 12, 312, 231, 321312, 22, 31, 321, 4, 123, 2, 231213, 4, 23, 312, 312, 312321}
I am trying get the min and max value using concurrency
in go lang.
Method I thought of
- I sliced the input array above at mid point
input[:len(input)/2]
input[len(input)/2:]
. So I have two arrays now and I want to calculate the min and max of each and pass it to channels below. Min value goes to mins channel and max value goes to max channel - Created two channel for storing minimum values(
mins
) and maximum values(maxs
) - Created two go routines for each sliced array which will calculate the min and max for each.
Problem
- Why I am getting a deadlock ? I am not not able to close it either
My attempt
package main
import "fmt"
func main() {
Minmax_Method([]int{20, 2112, 212, 12, 312, 231, 321312, 22, 31, 321, 4, 123, 2, 231213, 4, 23, 312, 312, 312321})
}
func Minmax_Method(input []int) {
mins := make(chan int) // channel for mins
maxs := make(chan int) // channel for maxs
go CalculateMinMaxWithChannel(input[:len(input)/2], mins, maxs)
go CalculateMinMaxWithChannel(input[len(input)/2:], mins, maxs)
// close(mins)
// close(maxs)
for i := range mins {
fmt.Println("Minimums", i)
}
for j := range maxs {
fmt.Println("Maximums", j)
}
}
func CalculateMinMaxWithChannel(input []int, mins chan int, maxs chan int) {
var min int = input[0]
var max int = input[1]
if min > max {
min = input[1]
max = input[0]
}
for i := 0; i < len(input); i {
if input[i] < min {
min = input[i]
}
if input[i] > max {
max = input[i]
}
}
mins <- min
maxs <- max
}
CodePudding user response:
Here is the revised Minmax_Method()
function, it is not the best solution but for now it will the problem of deadlock.
func Minmax_Method(input []int) {
var minC int = 0
var maxC int = 0
mins := make(chan int) // channel for mins
maxs := make(chan int) // channel for maxs
defer close(mins)
defer close(maxs)
go CalculateMinMaxWithChannel(input[:len(input)/2], mins, maxs)
go CalculateMinMaxWithChannel(input[len(input)/2:], mins, maxs)
go func() {
for i := range mins {
minC
fmt.Println("Minimums", i)
if minC == 2 && maxC == 2 {
os.Exit(0)
}
}
}()
go func() {
for j := range maxs {
maxC
fmt.Println("Maximums", j)
if minC == 2 && maxC == 2 {
os.Exit(0)
}
}
}()
for {
}
}
CodePudding user response:
Brits's code solves this problem well, here is more simplefy code
package main
import (
"fmt"
"sync"
)
func main() {
Minmax_Method([]int{20, 2112, 212, 12, 312, 231, 321312, 22, 31, 321, 4, 123, 2, 231213, 4, 23, 312, 312, 312321})
}
func CalculateMinMaxWithChannel(input []int, mins chan int, maxs chan int) {
var min = input[0]
var max = input[0]
for i := 0; i < len(input); i {
if input[i] < min {
min = input[i]
}
if input[i] > max {
max = input[i]
}
}
mins <- min
maxs <- max
}
func Minmax_Method(input []int) {
mins := make(chan int) // channel for mins
maxs := make(chan int) // channel for maxs
var wg sync.WaitGroup
wg.Add(2)
go func() {
CalculateMinMaxWithChannel(input[:len(input)/2], mins, maxs)
wg.Done()
}()
go func() {
CalculateMinMaxWithChannel(input[len(input)/2:], mins, maxs)
wg.Done()
}()
go func() {
wg.Wait()
close(mins)
close(maxs)
}()
var minC = input[0]
var maxC = input[0]
for mins != nil && maxs != nil {
select {
case m, ok := <-mins:
if !ok {
mins = nil
continue
}
if m < minC {
minC = m
}
case m, ok := <-maxs:
if !ok {
maxs = nil
continue
}
if m > maxC {
maxC = m
}
}
}
fmt.Println("Maximum:", maxC, "Minimum:", minC)
}