Live data from Hacker News

The Beauty of Concurrency in Go

pragprog.com

41–50 of 95 posts

Re: The Beauty of Concurrency in Go

#41
post #8

This article isn't bad... but it misses several important points of Go. I also note the article is 9 months old. In the hope that my criticism will be taken as constructive, with apologies for not writing detailed explanations: 1. Goroutines are not threads 2. type inference allows you to elide types in var declarations: var host = flag.String(... 3. Go's convention is to use camel case, not underscores. 4. Calling o…

How are goroutines not threads? Do you mean because it's possible for them to communicate without shared mutable state? Edit: Oh, apparently you all mean OS threads. So say so. (For example, in Haskell they're called threads without any implication that each one is an OS thread. Haskell's not unusual that way.)

Go schedules its own 'threads' (goroutines) to run on one or many (OS) threads.

In this case, threads refer to not-a-process units of execution in an operating system. For whatever its worth, Wikipedia defines threads as:

  the smallest sequence of programmed instructions that 
  can be managed independently by an operating system
  scheduler.
I think that's also the commonly accepted definition: that threads are related to the OS scheduler.

Re: The Beauty of Concurrency in Go

#42
post #34

There's so much code here. If I weren't sick, I'd submit a new version that: 1. Didn't reimplement io.Copy 2. Didn't avoid io.TeeReader 3. Didn't do weird things to avoid regular channel ranges. 4. Didn't do non-standard date formatting. 5. Didn't reinvent the log package. 6. Didn't try to convince anyone runtime.GOMAXPROCS(runtime.NumCPU()) was a good idea (it's not) In fact, maybe I will anyway. brb

> 6. Didn't try to convince anyone runtime.GOMAXPROCS(runtime.NumCPU()) was a good idea (it's not) So what is an appropriate GOMAXPROCS? As someone who has only dabbled in a few Go tutorials, I would imagine that you would want GOMAXPROCS to be NumCPU() (or even greater) so the goroutine thread pool could "fire on all pistons". Why does Go's scheduler default to GOMAXPROCS=1 instead of NumCPU()?

Or turning that around, do you think it requires all 8 of my cores to copy data over the network? Do you think the two lines of code + justification text provides sufficient value for this application to distract from the point of it in order to show why someone should override the default behavior?

Do you believe users shouldn't have any control over the number of cores any particular application consumes?

Have you measured the CPU contention of the application and determined that using more cores is worth the overhead of increased overhead of multi-thread exclusions (vs. more simple things happening directly in the scheduler)?

Overall, it has nothing to do with this article and now even more people are going to copy it in more unnecessary places as a cargo-cult "turbo button" for their programs.

If you are going to use an idiom like that, the least you could do is check for the GOMAXPROCS environment variable and only do this as a default when the user hasn't specified otherwise.

Re: The Beauty of Concurrency in Go

#43

Earlier quoted context omitted.

How are goroutines not threads? Do you mean because it's possible for them to communicate without shared mutable state? Edit: Oh, apparently you all mean OS threads. So say so. (For example, in Haskell they're called threads without any implication that each one is an OS thread. Haskell's not unusual that way.)

Go schedules its own 'threads' (goroutines) to run on one or many (OS) threads. In this case, threads refer to not-a-process units of execution in an operating system. For whatever its worth, Wikipedia defines threads as: the smallest sequence of programmed instructions that can be managed independently by an operating system scheduler. I think that's also the commonly accepted definition: that threads are related to…

The notion that goroutines aren't threads seems to exist primarly because Golang also makes use of OS-native threads in order to schedule goroutines, and so needs to draw a distinction in order to explain how the runtime works.

But that's just a detail. In reality, goroutines are threads; they're just userland, non-preemptive threads. Similar constructions have been available, even to C programmers, for well over a decade (and probably much longer).

Re: The Beauty of Concurrency in Go

#44
post #24

> > Notably, if a package is included but not used, Go treats this as an error and enforces removing unused declarations A good illustration that the Go designers didn't think their ideas through. This is a real pain in the butt when you are writing code and regularly commenting in and out sections of code while you are testing things. And every time you do this, you need to remove or restore the imports. And since G…

> good illustration that the Go designers didn't think their ideas through. This is a real pain in the butt when you are writing code and regularly commenting in and out sections of code while you are testing things.

How could it be that bad?

It's as simple as a compile, a click on the error message and adding a one line comment.

No worse than the standard practice of making sure your c/c++ code compiles without warnings with the maximimum warning level set.

Re: The Beauty of Concurrency in Go

#45
post #3

Ugh, I just finished writing the XMPP frontend for an XMPP/IRC bot I'm working on ( http://www.getinstabot.com ). The frontends are in Go for concurrency, and ferry messages back and forth from the channels to the backend. Let me tell you, that problem is hard . Go coped pretty well, but the final thing is a mess of global states, and it's pretty elegant for what the problem is. I was hoping to avoid having many movi…

> Something I miss from the language … Does sound like you want to use channels, and break your logic into small independent parts. You will have one goroutine using blocking Read() in a loop and feeding data to some channel. When it's done, you write to another channel that exists only for signaling: defer { doneChannel and then in your other goroutine: for { select { case data := The only things shared here are the…

> but I think "And what looks even better:

    defer close(doneChannel)
(it's also syntactically correct -- you ca't just have a defer block without a function invocation)

Re: The Beauty of Concurrency in Go

#46
post #21

This article and many like suffer from one of my huge pet-peeves, absolutely terrible coding conventions. I am a person who likes to scan articles, I'm busy and generally make a read now, read later, read never decision. The code from first scan was unreadable, short 1 character variable names, "why is there a hardcoded date marked 2006.01.02-15.04.05 there??", etc. Readable code takes a little more time - but it's w…

I'm afraid many of the conventions you complain about are standard Go, err, conventions... (Although see my complaint elsewhere.) Because they are so widely used, people who use Go won't bat an eyelid. Unfortunately that doesn't make the article a great introduction to Go. I hope these talks can help sell you on Go http://blog.golang.org/2013/01/two-recent-go-talks.html To be more explicit: Short variable names gener…

[deleted]

Re: The Beauty of Concurrency in Go

#47

The beauty of concurrency in Clojure: ; Rough sketch: def defines a var (pretend it's a reference) ; @ is used to dereference the future and block to wait for the result. (def f (future (Thread/sleep 10000) (println "done") 100)) user=> @f done 100 ;; Dereferencing again will return the already calculated value. => @f 100 http://clojuredocs.org/clojure_core/clojure.core/future Edit: And more importantly, there are wr…

Go doesn't "force" you to use one method of concurrency. It has more than one (you can do erlang-style share-nothing style or Java/C++ style of using mutexes to protect shared state from concurrent access). I know nothing about Closure so it's possible it has more features but it's not necessarily a good thing. Is the complexity of 4 different solutions worth it? (by "it" I mean: a programmer has to learn all of them…

So why use Go instead of node.js? You can probably take that reasoning and substitute "Go" for "Clojure", and "node.js" for "Go".

Go people would probably object that the things that Go adds, and that node.js lacks, aren't just window dressing -- sure, there are situations where a node.js-style fast event loop that avoids blocking operations is all you need, but there are also situations where you want something more like real threads, because the problem demands it.

I'm a lisper but not a Clojure expert - but I'd assume that Clojure people don't consider the existence of e.g. Actors to be "feature bloat". My impression is more that the difficult/special concurrency-enabling feature of the language is STM, and language-level support for different concurrency paradigms, implemented on top of STM, are probably low-hanging fruit once you've got it.

Re: The Beauty of Concurrency in Go

#48

Earlier quoted context omitted.

How are goroutines not threads? Do you mean because it's possible for them to communicate without shared mutable state? Edit: Oh, apparently you all mean OS threads. So say so. (For example, in Haskell they're called threads without any implication that each one is an OS thread. Haskell's not unusual that way.)

Go schedules its own 'threads' (goroutines) to run on one or many (OS) threads. In this case, threads refer to not-a-process units of execution in an operating system. For whatever its worth, Wikipedia defines threads as: the smallest sequence of programmed instructions that can be managed independently by an operating system scheduler. I think that's also the commonly accepted definition: that threads are related to…

It is really common for Go programmers (I've even seen members of the Go core team do it) to say 'thread' when they mean goroutine. It is important to recognize there is a difference, but calling someone out for saying 'thread' when they mean 'goroutine' is pedantic bullshit on the order of calling someone out for calling a class method in an OO language a function.

Re: The Beauty of Concurrency in Go

#49

The beauty of concurrency in Clojure: ; Rough sketch: def defines a var (pretend it's a reference) ; @ is used to dereference the future and block to wait for the result. (def f (future (Thread/sleep 10000) (println "done") 100)) user=> @f done 100 ;; Dereferencing again will return the already calculated value. => @f 100 http://clojuredocs.org/clojure_core/clojure.core/future Edit: And more importantly, there are wr…

Go doesn't "force" you to use one method of concurrency. It has more than one (you can do erlang-style share-nothing style or Java/C++ style of using mutexes to protect shared state from concurrent access). I know nothing about Closure so it's possible it has more features but it's not necessarily a good thing. Is the complexity of 4 different solutions worth it? (by "it" I mean: a programmer has to learn all of them…

[deleted]

Re: The Beauty of Concurrency in Go

#50

Earlier quoted context omitted.

Go schedules its own 'threads' (goroutines) to run on one or many (OS) threads. In this case, threads refer to not-a-process units of execution in an operating system. For whatever its worth, Wikipedia defines threads as: the smallest sequence of programmed instructions that can be managed independently by an operating system scheduler. I think that's also the commonly accepted definition: that threads are related to…

It is really common for Go programmers (I've even seen members of the Go core team do it) to say 'thread' when they mean goroutine. It is important to recognize there is a difference, but calling someone out for saying 'thread' when they mean 'goroutine' is pedantic bullshit on the order of calling someone out for calling a class method in an OO language a function.

Oh I'm not (I didn't meant to?) calling parent out, I was just trying an explanation.
Post reply on HN