News for hackers. Stuff that matters.
Re:Go Things I Love: Channels and Goroutines by iamjfu on Tuesday January 07, 2020 @08:09AM (#21979571)
Hi, author of the post here. Which example doesn't work? I just pasted the communicate by sharing memory example into the go playground: https://play.golang.org/p/bWtyGTC-EsC and it gives the same length every time. Am I missing something or are you referring to a different example?

> More on-topic, channels have their own tradeoffs. I often reach for WaitGroups and mutexes instead of channels, because things can get complicated fast when you're routing data around with channels

You're absolutely right. I certainly didn't intend to give a blanket recommendation. It's more of a, "If you're sharing memory, might it become clearer if you share memory by communicating?" I was worried that the simplistic examples would not properly represent the cases I was thinking of. I think that's a communication error on me.

Re:Go Things I Love: Channels and Goroutines by modernerd on Tuesday January 07, 2020 @08:31AM (#21979715)
I think it's only consistent in play.golang.org because results are cached: https://blog.golang.org/playground.

If I run it locally it's not consistent:

    go run lock/main.go
    [3 0 1 2 5 4 6 9 7 8] 10⏎
    
    go run lock/main.go
    [1 5 6 7 8 0] 6⏎
    
    go run lock/main.go
    [0 3 1 2 4 5 6 7 8] 9⏎
Here's a version that does work for me: https://play.golang.org/p/b6bRb9pgIGZ

The issue is that appending to slices concurrently is not safe, so you have to use a lock around the append or similar.

Re:Go Things I Love: Channels and Goroutines by DougBTX on Tuesday January 07, 2020 @11:03AM (#21981198)
In a way this supports the argument for the "Do not communicate by sharing memory; instead, share memory by communicating" mantra, as in a language with no compile-time checks for incorrect use of shared memory, it is very easy to get it wrong.
Re:Go Things I Love: Channels and Goroutines by modernerd on Tuesday January 07, 2020 @11:06AM (#21981238)
Yes, it looks like the author has updated their post to say as much following the comments here.
Re:Go Things I Love: Channels and Goroutines by iamjfu on Tuesday January 07, 2020 @04:59PM (#21985456)
I have. I didn't have time to rewrite it (I'm working, and I didn't want to take it down) so I added a few caveats. I am going to research this more and follow up again. Thanks again to everyone for the great responses. I learned a lot from the comments here.
Re:Go Things I Love: Channels and Goroutines by empath75 on Tuesday January 07, 2020 @10:07AM (#21980568)
If you try to run a naive version of this in rust, the compiler won't even run it.

https://play.rust-lang.org/?version=stable&mode=debug&editio...

I'm a beginner at rust, but this is the version I came up with that compiles and works:

https://play.rust-lang.org/?version=stable&mode=debug&editio...

Re:Go Things I Love: Channels and Goroutines by iamjfu on Tuesday January 07, 2020 @08:52AM (#21979853)
TIL. That's a huge flaw. Thanks so much for your response!
Re:Go Things I Love: Channels and Goroutines by modernerd on Tuesday January 07, 2020 @09:33AM (#21980211)
Welcome! It's the same for other data structures, by the way (not just slices) — maps are not safe for concurrent writes either. (The rationale seems to be that users of the data types can choose whether to make them safe for concurrent use or not depending on the use case.)

I found this helpful: https://youtu.be/29LLRKIL_TI?t=1340

Re:Go Things I Love: Channels and Goroutines by irq-1 on Tuesday January 07, 2020 @11:13AM (#21981319)
They added sync.Map

> Map is like a Go map[interface{}]interface{} but is safe for concurrent use by multiple goroutines without additional locking or coordination. Loads, stores, and deletes run in amortized constant time.

https://golang.org/pkg/sync/#Map

Re:Go Things I Love: Channels and Goroutines by masklinn on Tuesday January 07, 2020 @11:10AM (#21981281)
> The rationale seems to be that users of the data types can choose whether to make them safe for concurrent use or not depending on the use case.

Also that for most uses a concurrent map is way overkill, and a thread-safe one is both costly and basically useless (hence the Java folks not keeping the thread-safety when migrating from Hashtable to HashMap).

On the other hand they're kinda shit given how awful non-builtin data structures are in Go, and how easy it is to "leak" maps between goroutines.

Re:Go Things I Love: Channels and Goroutines by vips7L on Wednesday January 08, 2020 @07:56AM (#21990954)
Hashtable used a giant mutex when locking.. it was just slow. Especially when compared to ConcurrentHashMap.
Re:Go Things I Love: Channels and Goroutines by shhsshs on Tuesday January 07, 2020 @07:28PM (#21986901)
Results are cached, but the main reason the example “works” is because the playground has GOMAXPROCS set to 1, meaning only a single goroutine will be running at any given point.
Re:Go Things I Love: Channels and Goroutines by modernerd on Wednesday January 08, 2020 @02:22AM (#21989102)
That makes sense, thanks for the correction.
Re:Go Things I Love: Channels and Goroutines by TomNomNom on Tuesday January 07, 2020 @08:32AM (#21979723)
Ran the example on my machine and can confirm it's broken.

Be careful relying on the results of the Go playground; it has a bunch of differences and probably has GOMAXPROCS set to 1, which most other systems will not.

You need a sync.Mutex or similar protecting your call to append :)

Re:Go Things I Love: Channels and Goroutines by carbocation on Tuesday January 07, 2020 @08:27AM (#21979674)
The Go playground is designed to be deterministic, right? Not sure that’s a useful test. On mobile so I can’t compile right now or else I’d take a look.
Re:Go Things I Love: Channels and Goroutines by elithrar on Tuesday January 07, 2020 @08:34AM (#21979735)
Correct. Results are cached for the same program “ID”.