4 ms·
Modified the above to https://go.dev/play/p/DRXyvRHsuAH https://go.dev/play/p/DRXyvRHsuAH You get the first result in results[0] thanks to `atomic.Int32`.
by lenkite 2y ago
Modified the above to https://go.dev/play/p/DRXyvRHsuAH 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)
}
- Thorrez 2y agoThis will wait up to 1 second before showing a result when a result comes in. I'm pretty sure Chris doesn't want any waiting like that. This will also print some results multiple times. I think Chris wants to print each result once.
- lenkite 2y agoIt is utterly clear that the random wait is not intrinsic to the logic - it was only added for demonstration to simulate varying duration of requests. You can simply comment out the println and just pick the first results[0]. Again, the repeated println for all results was only added for demonstrative clarity. Frankly, the above satisfies all primary goals. The rest is just nitpicking - without a formal specification of the problem one can argue all day.
- Thorrez 2y ago>It is utterly clear that the random wait is not intrinsic to the logic - it was only added for demonstration to simulate varying duration of requests. I wasn't talking about the random wait at all. I was talking about for range time.NewTicker(time.Second).C { fmt.Println("Results: ", results) } >You can simply comment out the println and just pick the first results[0]. When should we look at results[0]? There needs to be some notification that results[0] is ready to be looked at. Similarly with all the rest of the results. >Frankly, the above satisfies all primary goals. The rest is just nitpicking - without a formal specification of the problem one can argue all day. I guess we have to disagree. From my reading of the blog post it was pretty clear what Chris wanted, and the code you provided didn't meet that.
- lenkite 2y agoYou can completely ignore that pretty print function as it not essential to the goal. Revised example without pretty-print at https://go.dev/play/p/LkAT_g95BLO https://go.dev/play/p/LkAT_g95BLO As soon as you have completed `<-finished` in the main go-routine, it means `results[0]` has been populated and is ready for read. If you want to wait till all results are available, then perform `<-finished`, `len(results)` times. (Or use sync.WaitGroup) package main import ( "fmt" "math/rand" "sync/atomic" "time" ) func main() { args := []int{5, 2, 4, 1, 8} var resultCount atomic.Int32 resultCount.Store(-1) results := make([]int, len(args)) finished := make(chan bool, len(args)) slowSquare := func(arg int, fnNum int) { randomMilliseconds := rand.Intn(1000) blockDuration := time.Duration(randomMilliseconds) * time.Millisecond fmt.Printf("(#%d) Squaring %d, Blocking for %d milliseconds...\n", fnNum, arg, randomMilliseconds) <-time.After(blockDuration) resultIndex := resultCount.Add(1) results[resultIndex] = arg * arg fmt.Printf("(#%d) Squared %d: results[%d]=%d\n", fnNum, arg, resultIndex, results[resultIndex]) finished <- true } for i, x := range args { go slowSquare(x, i) } fmt.Println("(main) Waiting for first finish") <-finished fmt.Println("(main) First Result: ", results[0]) }
- Thorrez 2y ago
- SkiFire13 2y agoThis is a data race between the write to `results[idx]` in the `slowSquare` goroutine and the read of `results` in the `prettyPrinter` goroutine.
- deleted 2y ago[deleted]