5 ms·
What do you mean by "removal of the thread?" Go is multithreaded and is vulnerable to classic thread-safety issues, like races and reentrancy.
by ridiculous_fish 11y ago
What do you mean by "removal of the thread?" Go is multithreaded and is vulnerable to classic thread-safety issues, like races and reentrancy.
- gtremper 11y agoHe's referring to interacting with goroutines rather than system threads directly.
- eropple 11y agoWhich Go neither invented nor seriously popularized, unless we are to rewrite history to ignore the actor systems in common use on both the CLR and the JVM (to say nothing of Erlang et al, but "popularized" rather rules that out) well before Go's public release. Unless the qualifier is "popularized among Ruby and Python people," and, well, sure, but the number of Prometheuses to bring fire to those folks is large and ever growing.
- hacknat 11y agoGo didn't invent co-routines, but the primitives of channels and the select statement that go along with them, while not ground breaking, amazingly simplify a lot of concurrency patterns that can get overly bloated and/or difficult to reason about in other languages. I have simply never seen another language that makes it as easy as Go does to reason about parallelism/concurrency (maybe Erlang).
- kasey_junk 11y agoThis is an attitude I've encountered before & can't really get my head around. Channels are a really bad implementation of a queued message concurrency pattern that has been standard in other languages for years. The select pattern maps directly to any number of interupt style programming abstractions that are available in every language I've programmed in the last 15 years. Quite simply I find the go concurrency story primitive to the point of painful. I'd love to figure out why my opinion on that is so far outside the common refrain
- meowface 11y agoWhile channels definitely aren't anything new, and are just a renamed locking queue structure, why do you say they're "a really bad implementation"?
- kasey_junk 11y agoThey don't scale well because of lock contention, the syntax is missing standard concepts like timeouts etc, & the behavior around edge cases around initialization, closed channels, nil values etc is bizarre.
- azth 11y agoAren't they "lock-free" though?
- kasey_junk 11y agoNot in the least. They are a thin veneer on top of a giant mutex.
- azth 11y agoThat's quite disturbing :P Any idea why they didn't implement channels as a lock-free list, ala java.util.concurrent.ConcurrentLinkedQueue?
- eropple 11y agoI don't presume to speak for Go's developers, but I would guess because it's not that big a deal, especially in a cooperative environment. "If I can't obtain the mutex, yield" is a perfectly defensible thing, and is easier to write and probably to maintain than a lock-free list. Having Java's concurrent stuff is nice, don't get me wrong, but I can understand it not being the biggest priority in the world to go rebuild that later. As I've mentioned elsewhere in this thread, there are much bigger beefs.
- eropple 11y agoLanguages don't need to make parallelism and concurrency easy if they're sufficiently expressive by themselves. Go bakes in things that a competent programmer doesn't need baked, while ignoring things that make a competent programmer better at their jobs (yes, it's the generics problem again!). Making channels primitives isn't a positive to me when it's something I can implement as well or better in userland--which I can, even in a language as middling and Java-1.1y as Go. Go's channels are effectively a locking message queue (Java's had one of these since at least Java 5) plus a (usually global) thread pool. Not too long ago I implemented the moral equivalent in C++11, using only the standard library and in a unit-testable format, in forty-eight lines. Selecting across them is nice syntactic sugar, but is likewise able to be mimicked in plenty of other languages. Or, alternatively, I can use way more pleasant abstractions like Akka or Celluloid in not-Go languages (sending up Erlang when Akka provides a very similar experience in Scala or Kotlin--even Java, if you're using Java 8--is...curious). I guess you can make an argument for TOOWTDI, but I don't find that to be persuasive when the OW in question is middling.
- deleted 11y ago[deleted]
- mkup 11y agoGo runtime library contains user-space scheduler which maps lightweight Go threads to heavyweight OS threads in M:N manner. By the way, Go runtime library allows running user code in only one OS thread per process, all other OS threads must be in the state of blocking system call. So, no mutexes / interlocked instructions are required to access global data from goroutines, but this comes at the cost of reduced parallelism compared to C/C++ (which author of original article seems to be unaware of).
- NateDad 11y agoWow, uh no. You're 100% wrong, unless I'm misunderstanding you. You can absolutely have user code running on N threads simultaneously (where N is the number of cores of your machine). And you definitely do need mutexes. Your statement holds only if GOMAXPROCS is 1, which granted used to be the default, but was always able to be increased, and the default now is the number of cores on the machine.
- mkup 11y agoAh, now I see these things changed recently. I wrote original comment because at the time of Go 1.1 or 1.2 my colleague wrote racy code which accessed global variable without mutexes. I tried to educate him to use mutexes, by reducing his code to the minimal version demonstrating race condition, but failed. Then I digged into the source code of Go runtime library and discovered that only one thread could be in the running state at any moment (other threads could be in the state of blocking system call). So, things changed since that time. OK, nice to see Go evolves. Interesting, how many code in production got broken during upgrade to Go 1.5 due to this backwards-incompatible change. Overall situation seemed totally reasonable to me at that time: Go is a language for average programmer, so it should prefer safely over runtime performance; and coding cowboys who are comfortable with mutexes, interlocked instructions, memory barrier instructions, and lock-free data structures will use C/C++ anyway.
- tcard 11y agoBut that wasn't true either at the time of Go 1.1, nor ever I believe. It was the _default_ behavior to have a single core running at a time, but you could just tweak that with the [GOMAXPROCS](https://godoc.org/runtime#GOMAXPROCS https://godoc.org/runtime#GOMAXPROCS) variable, documented everywhere. (That's what changed in Go 1.5; now the default for GOMAXPROCS is the number of cores in the machine.)