News for hackers. Stuff that matters.
Re:Sane Concurrency with Go by shanemhansen on Wednesday March 12, 2014 @04:33PM (#7388182)
Go has some great high level concurrency primitives with channels and goroutines, but honestly the first function could have been written by sync.Mutex.Lock/defer sync.Mutex.Unlock.
Re:Sane Concurrency with Go by nonsequitarian on Wednesday March 12, 2014 @04:40PM (#7388237)
Absolutely true. And if I were writing this for actual real world use then I would have done so. The main technique I was trying to get to was tightly coupling a struct w/ an internal event loop, though, so I allowed myself some awkward code (called out as such in the post) to build up to that point.
Re:Sane Concurrency with Go by voidlogic on Wednesday March 12, 2014 @04:35PM (#7388198)
I was about to say this, using channels when want you want is a Mutex will result in awkward code.

>One of Go’s selling points is that there are some very useful concurrency primitives baked right into the language.

Lets state this, not use any of said primitives, and then complain the language is broken...

Re:Sane Concurrency with Go by rakoo on Wednesday March 12, 2014 @05:29PM (#7388526)
Although more verbose, I find this pattern much better than mutexes.

The problem with mutexes is that they are some kind of cheap way for the developer to say "stop the world while I think", but they require you to be quite aware of what happens in an object, too much I think.

In this example you'd have a mutex for the Account, so each time you want to change the amount you need to lock and unlock it. That's trivial for an object like that, but it can quickly become complex: one mutex is not enough because it blocks the whole object, so you start having multiple mutexes. But then you don't remember which mutex blocks what so you must have some good documentation about that, but the documentation is not as well maintained as the rest so it starts rotting. And then your file spreads among so many lines you can't quite grasp all the ways parallelism can kill you.

In the given example, the mindset is different: _all_ methods called from the outside are non-modifying, they only stack the change to be made. The actual data manipulation is done in a very tight loop that does a very simple thing, and nothing outside of this loop ever deals with memory. As a developer, you can fit all the code that can be "dangerous" in a mere 7 lines of code, instead of having it spread among the file.

I concure it's a different mindset, quite different at that, but it's a pretty good one (ang go makes it very pleasant)

Re:Sane Concurrency with Go by tomsthumb on Wednesday March 12, 2014 @07:04PM (#7389031)
This is nifty perspective. Thank you for the useful info.
Re:Sane Concurrency with Go by nonsequitarian on Wednesday March 12, 2014 @04:44PM (#7388266)
Sorry, where's the part where I complained that the language is broken? I said that Go doesn't protect you from mutating shared state across multiple concurrent goroutines. Not a very controversial statement, that.
Re:Sane Concurrency with Go by voidlogic on Wednesday March 12, 2014 @04:53PM (#7388330)
What you go on to say is:

But how does Go’s approach to concurrency fare when viewed through the lens of encouraging code that supports local reasoning? Not very well, I’m afraid. Goroutines all have access to the same shared memory space

The article is flawed because you: 1. Base it on Go failing to protect you, when in actually you fail to use any of Gos "very useful concurrency primitives baked right into the language" 2. When you choose to use these primitives you choose the the wrong primitive that results in a much more verbose and complex solution then is necessary.

It would have been much better had you: 1. Showed why the solution with no protection is unsafe (and mention its unsafe in just about any mainstream language) 2. Show a mutuex solution 3. Show a channel based solution

Re:Sane Concurrency with Go by nonsequitarian on Wednesday March 12, 2014 @05:19PM (#7388474)
Snark aside, I added a bit to clarify that the first example is contrived, implemented as such for illustrative purposes, and a mutex would actually be a better choice in the trivial case.
Re:Sane Concurrency with Go by voidlogic on Wednesday March 12, 2014 @05:51PM (#7388637)
Thank you, I appreciate that.

I would have understood snarking at my original (admittedly somewhat snarky) comment. I'm not sure why you felt the need to snark at my constructive criticism, which you actually took-

Re:Sane Concurrency with Go by nonsequitarian on Wednesday March 12, 2014 @10:20PM (#7389737)
It's maybe a bit silly having a conversation about tone on Hacker News, but generally people tend to respond better when you don't state opinions, especially critical ones, as though they're fact. See "The article is flawed because you..." and "It would have been much better had you..." I statements FTW.

I don't think the original version was particularly flawed, and your description of why you think it was doesn't make a lot of sense to me. But I added a note anyway to make it clear that I do in fact know about the alternative approaches, and that I made the choices I made deliberately and not out of ignorance.

Regardless, I appreciate you taking the time to read it, and to give your feedback. Cheers.

Re:Sane Concurrency with Go by fulafel on Wednesday March 12, 2014 @05:22PM (#7388490)
He uses channels, which are the main Go primitive. "Share by communicating" and all that.
Re:Sane Concurrency with Go by voidlogic on Wednesday March 12, 2014 @05:48PM (#7388621)
>>which are the main Go primitive.

When it comes to protecting a structs state, in most Go code (including the standard library) RW/Mutexes are the "go to" synchronization primitive. Channels are more commonly used for communication between longer running goroutines.

Re:Sane Concurrency with Go by nonsequitarian on Wednesday March 12, 2014 @05:03PM (#7388384)
Thanks for explaining to me the error of my ways.
Re:Sane Concurrency with Go by GauntletWizard on Thursday March 13, 2014 @04:48PM (#7394905)
I tried an experiment in Go a few weeks back; The difference in writing to a logfile between using synchronous access (wrapped in Mutex.Lock) and passing a reference through a buffered channel (such that the ownership of the object was received along the channel). There was less than a 1% advantage to the Mutex, and the code was surprisingly clean with channels.
Re:Sane Concurrency with Go by amix on Wednesday March 12, 2014 @06:39PM (#7388897)
I was also thinking this while reading this (and I am very new to Go). Here's how I would write this in Go: https://gist.github.com/amix/9517995

I think this is the idiomatic way to implement this. It will lock the account every time you try to deposit to it (so other goroutines can't do it).

Re:Sane Concurrency with Go by xkarga00 on Wednesday March 12, 2014 @10:07PM (#7389706)
Using mutexes isn't considered as idiomatic Go code
Re:Sane Concurrency with Go by zaphar on Thursday March 13, 2014 @12:23AM (#7390035)
Mutexes are absolutely idiomatic Go code. In fact the Core developers on the ML will often suggest them as a simplification over goroutines for synchronizing access to a shared resource. I'm not sure where you get the idea that they aren't idiomatic.
Re:Sane Concurrency with Go by xkarga00 on Thursday March 13, 2014 @04:22AM (#7390600)
Probably by making the mistake to read the Effective Go.

http://golang.org/doc/effective_go.html#concurrency

"Do not communicate by sharing memory; instead, share memory by communicating.

This approach can be taken too far. Reference counts may be best done by putting a mutex around an integer variable, for instance. But as a high-level approach, using channels to control access makes it easier to write clear, correct programs. "

Re:Sane Concurrency with Go by amix on Thursday March 13, 2014 @06:09AM (#7390893)
I don't really think what I suggest goes against the article you link to. It basically says: use channels when appropriate, but sometimes the best approach is to use locks.

E.g. An bank account is shared state (similar to a reference count) and the best approach is to put a mutex around it instead of fighting with channel synchronization.

Re:Sane Concurrency with Go by xkarga00 on Thursday March 13, 2014 @07:15AM (#7391085)
There are no implications here, it's stated pretty explicitly:

"Reference counts MAY be best done by putting a mutex around an integer variable, for instance. BUT as a high-level approach, using channels to control access makes it easier to write clear, correct programs."

There is a difference between what someone with a background from other mainstream programming languages might think would be the best approach to locking (mutexes) and the idiomatic Go approach (unbuffered channels).

Re:Sane Concurrency with Go by nkozyra on Wednesday March 12, 2014 @10:11PM (#7389718)
Well anything other than direct channel <-> goroutine is not considered idiomatic.