top | item 41693416

(no title)

pbnjay | 1 year ago

Isn't it even simpler in Go? No channels necessary, Each goroutine gets an index or slice, and writes the results to a shared array.

All you need is the goroutines to report when done via a WaitGroup.

discuss

order

teraflop|1 year ago

That doesn't satisfy the "report the results as they become available" requirement.

The desired behavior is that printing the first result should only wait for the first result to be available, not for all the results to be available.

lenkite|1 year ago

Modified the above to https://go.dev/play/p/DRXyvRHsuAH You get the first result in results[0] thanks to `atomic.Int32`.

    package main

    import (
     "fmt"
     "math/rand"
     "sync/atomic"
     "time"
    )

    func main() {
     args := []int{5, 2, 4, 1, 8}
     var indexGen atomic.Int32
     indexGen.Store(-1)
     results := make([]int, len(args))
     finished := make(chan bool)

     slowSquare := func(arg int, index int) {
      randomMilliseconds := rand.Intn(1000)
      blockDuration := time.Duration(randomMilliseconds) * time.Millisecond
      fmt.Printf("Squaring %d, Blocking for %d milliseconds...\n", arg, randomMilliseconds)
      <-time.After(blockDuration)
      idx := indexGen.Add(1)
      results[idx] = arg * arg
      fmt.Printf("Squared %d: results[%d]=%d\n", arg, idx, results[idx])
      finished <- true
     }

     prettyPrinter := func() {
      for range time.NewTicker(time.Second).C {
       fmt.Println("Results: ", results)
      }
     }
     go prettyPrinter()
     for idx, x := range args {
      go slowSquare(x, idx)
     }
     <-finished

     fmt.Println("First Result: ", results[0])
     fmt.Println("So-far Results: ", results)

    }