0

I have a loop throwing multiple go routines, they call a function that makes a http get petition and calculate and object.

I want to recover the result of all those routines. I tried using channels, but hey are empty, even if I force wait for all the routines to be done.

This is the code that starts the routines:

func main() {
    pairs := getPairs() //Returns an array of strings
    c := make(chan result)
    for _, product := range pairs {
        go getScore(product.Symbol, 1, c)
    }
    fmt.Println(len(c))
    time.Sleep(5000 * time.Millisecond)
    fmt.Println(len(c))
}

And at the end of getScore() I do this, c being the name of the channel in the function and res the result of the function

c <- res

The length of the channel is 0 in both prints.

What's the best way to get the result of the functions?

Enrique Alcazar
  • 381
  • 7
  • 21

2 Answers2

0
c := make(chan result)

Creates an unbuffered channel. Therefore send statements, such as

c <- res

cannot proceed until another goroutine is attempting a receive operation.

In other words, execute the number of receive operations in your main goroutine matching the number of sends that will be attempted from other goroutines. Like this:

for _, product := range pairs {
    go getScore(product.Symbol, 1, c)
}
for x := 0; x < len(pairs); x++ {
    fmt.Println(<-c)
}

See the Go Tour section on channels, and the Effective Go section on channels for more information.

jrefior
  • 4,092
  • 1
  • 19
  • 29
0

A channel is a synchronization prototype against a shared memory (in simple point of view). A buffered channel has a length but not a regular channel. Buffered channel is useful in little bit cases but not as a general approaches.

The simplest way to Just add a loop by range of pair or len of pairs:

// start processing
for _, product := range pairs {
    go getScore(product.Symbol, 1, c)
}
// getting a result
for i:=0; i<len(pairs); i ++ {
    result := <-c
    // process a result value
}

Or another way is collecting result in another grouting:

// result and sync variable
var (
   wait sync.WaitGroup
   result int32
) 
// start processing
for _, product := range pairs {
    wait.Add(1)
    go getScore(product.Symbol, 1, c)
    go func() {
        defer wait.Done()
        // simple accumulate or maybe more complicated actions
        atomic.AddInt32(&result, <-c)
    }()
}
// wait finishing
wait.Wait()
alexey_p
  • 196
  • 7