Live data from Hacker News

The Beauty of Concurrency in Go

pragprog.com

61–70 of 95 posts

Re: The Beauty of Concurrency in Go

#61
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()?

In my experience the majority of well-written concurrent programs become I/O-bound on a single processor. It's pointless to add more processors to that, and can only slow you down, and Go programs are far better behaved in the non-parallel case.

At other times you should think about the number of processors you want to occupy. If the objective is to behave like an appliance, then 1:1 schedulers:cpus is not a bad ballpark.

Re: The Beauty of Concurrency in Go

#62
post #6
post #4

This has finally let me figure out what annoys me about Go, its a cargo-cult language. People saw that Erlang's Actors/processes were really popular and made it easy to write good, concurrent software. They then went away and implemented their own language with lightweight processes and message passing, but missed the fact that actors are the price you have to pay for the benefits of not sharing mutable data. And Go…

Doesn't go just implement Hoare's communicating sequential processes, as does Erlang? They share the same inspiration. You don't need to share state data between your goroutines if you don't want to either just like you don't have to use mnesia to share state between erlang processes if you don't want to. I don't think you can really accuse go of being a cargo cult language either, Rob Pike has implemented CSP multip…

Doesn't go just implement Hoare's communicating sequential processes, as does Erlang? They share the same inspiration.

Nope: The original Communicating Sequential Processes model[24] published by Tony Hoare differed from the Actor model because it was based on the parallel composition of a fixed number of sequential processes connected in a fixed topology, and communicating using synchronous message-passing based on process names (see Actor model and process calculi history). Later versions of CSP abandoned communication based on process names in favor of anonymous communication via channels, an approach also used in Milner's work on the Calculus of Communicating Systems and the π-calculus.¹

¹: https://en.wikipedia.org/wiki/Actor_model#Contrast_with_othe...

Re: The Beauty of Concurrency in Go

#63
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…

Your critique (which seems valid; I'm not a Go expert) does not exactly instill confidence in the Pragmatic Programmer (PP) brand.

When I read material from them, I would have assumed I'd be seeing "idiomatic code from an expert"...not "hey, I'm a newbie hacking my way around in a new language, here's what I typed out in 2 days of playing with it".

I mean, I understand they're big on the "learning a new language on a regular basis thing", but when I see code published like this, specifically from their brand, I go into it thinking "okay, this should be high quality, idiomatic code."

...guess I'll be more careful with that assumption.

(EDIT: If this is just some personal blog, I guess I'd understand; I saw "magazine" in the URL and got the impression this was published as part of their magazine/PDF series.)

Re: The Beauty of Concurrency in Go

#64

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…

Its not a commonly accepted "definition" - threads are a general concept that encompass several different forms of concurrency. It may be commonly assumed that the term "thread", in absence of any other qualifier, refers to OS-level threads, however even that is context dependent. The Wikipedia page introduction is poorly written.

However the more salient point here is the OP was either being lazy by saying "goroutines are not threads", or actually doesn't understand the concept of lightweight threads. Along the lines of Rob Pike's own explanation on the matter, he maybe should have said "goroutines provide concurrency but not parallelization".

Re: The Beauty of Concurrency in Go

#65

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…

Futures in C++11 are similar: int x = std::async([]()->int{ return 100; }); std::cout Which isn't as nice as closure. Go could probably benfit from having a standard futures tool. I guess something along the lines of: type Future { Wait() interface{} } func newFuture(func interface{}, args ...interface{}) Future

I got this wrong. std::async should not return an int. It's should be std::future

Re: The Beauty of Concurrency in Go

#66

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…

> that threads are related to the OS scheduler

It is actually common for people to talk about green threads (http://en.wikipedia.org/wiki/Green_threads) in the same vain as OS threads.

Re: The Beauty of Concurrency in Go

#67
post #36
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…

False. The Go designers have explained many times why they made unused imports an error. In particular unused dependencies slow down compilation. There's even a FAQ: http://golang.org/doc/faq#unused_variables_and_imports . A trivial workaround to silence the compiler errors during development is to use blank identifiers ( http://golang.org/doc/effective_go.html#blank_unused ). I use them all the time. You may disagre…

Maybe they did think it through, but their conclusion reveals some inexperience.

It's impractical on many levels. Thus the need for kludgy solutions like blank identifiers. I'd rather see a strict mode or some other type of compiler flag.

Re: The Beauty of Concurrency in Go

#68
post #67
post #36

Earlier quoted context omitted.

False. The Go designers have explained many times why they made unused imports an error. In particular unused dependencies slow down compilation. There's even a FAQ: http://golang.org/doc/faq#unused_variables_and_imports . A trivial workaround to silence the compiler errors during development is to use blank identifiers ( http://golang.org/doc/effective_go.html#blank_unused ). I use them all the time. You may disagre…

Maybe they did think it through, but their conclusion reveals some inexperience. It's impractical on many levels. Thus the need for kludgy solutions like blank identifiers. I'd rather see a strict mode or some other type of compiler flag.

Maybe you don't realize that "they" includes Ken Thompson himself... You may disagree with the Go design team's decisions, but it's amusingly absurd to accuse them of inexperience.

Re: The Beauty of Concurrency in Go

#69
post #68
post #67

Earlier quoted context omitted.

Maybe they did think it through, but their conclusion reveals some inexperience. It's impractical on many levels. Thus the need for kludgy solutions like blank identifiers. I'd rather see a strict mode or some other type of compiler flag.

Maybe you don't realize that "they" includes Ken Thompson himself... You may disagree with the Go design team's decisions, but it's amusingly absurd to accuse them of inexperience.

> Maybe you don't realize that "they" includes Ken Thompson himself... You may disagree with the Go design team's decisions, but it's amusingly absurd to accuse them of inexperience.

Not really, if anything, Go shows that its designers have a lot of inexperience when it comes to modern language design.

Go would have been a kille language in the late 90's but it seems to ignore everything that we've learned about language design in the past decade.

Re: The Beauty of Concurrency in Go

#70

Earlier quoted context omitted.

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.

Sorry if where I replied made this confusing, I wasn't really talking about you nor even did I mean it as a personal thing against Jabbles who did the actual "calling out" of mixing threads and goroutines.

As I mentioned, knowing the difference is actually a good thing so your post is really helpful. My point is just that the two concepts are so intertwined and overlapping that I think it is silly for someone to correct someone's terminology on this (as Jabbles did, though I admit I share some of his(?) other concerns with the OP), particularly in cases where it is clear the person is pretty familiar with goroutines and how they operate.

Post reply on HN