Home > Blockchain >  Find the min and max of array using the go lang concurrency?
Find the min and max of array using the go lang concurrency?

Time:10-11

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

  1. 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
  2. Created two channel for storing minimum values(mins) and maximum values(maxs)
  3. Created two go routines for each sliced array which will calculate the min and max for each.

Problem

  1. 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)
}
  • Related