Live data from Hacker News

Data Race Patterns in Go

eng.uber.com

171–180 of 205 posts

Re: Data Race Patterns in Go

#171

Earlier quoted context omitted.

> A Data Race is any time when there's concurrent modification of a memory value I do want to nail down the terminology, so help me with this scenario: Two simultaneous relaxed atomic writes to the same variable from different threads. To my understanding, this is not a data race (since this is allowed, while data races are never allowed), but it is concurrent. Do I have that right?

Well spotted. This is arguably a hole, albeit a deliberate one. In practice the main reason people do this is collecting some sort of metric, whose exact value is unimportant and which anyway isn't contemplated by the machine. If your program tries to actually act on this data then yeah, you have successfully made your own life unnecessarily exciting and debugging your program may be difficult. I think it's fair to s…

As an interesting example of doing something meaningful with relaxed arithmetic, Arc uses a relaxed fetch_add to increment the refcount: https://doc.rust-lang.org/src/alloc/sync.rs.html#1331-1343. Decrementing, however, uses acquire-release. Apparently shared_ptr in C++ is similar.

Re: Data Race Patterns in Go

#172
post #142

Earlier quoted context omitted.

I meant it more in that "first-class" tends to mean "this is a thing that is represented in the language / type system". Go has first-class functions, because you can make a `var fn func() string` field/variable/argument/etc that holds a reference to a func that returns a string. Go does not have first-class types, because you can't reference or store a type directly. You can use reflection to pass a reflected thing…

I mean, Go clearly has goroutines as a “first class” concept for some value of “first class”, and (as they are a sort of thread) goroutines are concurrency. This is to say, I don’t think your claim about “must have async/await in order to have first class concurrency” is correct in any formal sense (maybe you’re defining “first class concurrency” as requiring async/await rather than asserting that this is what first-…

By that description though, Go also has first class types. And that kind of makes the distinction meaningless because essentially every programming language has types.

There might be room to claim first-class support for green threads? But if so it's a very weak "first class" since all you can do is start them.

Re: Data Race Patterns in Go

#173

Earlier quoted context omitted.

> how to build low-latency applications with ease too That's a bit of a stretch. Surely, you can build low-latency apps, but I'd be very careful with the "with ease" bit. Low-latency Java often means zero heap allocations, aggressive object avoidance / reuse, heavy use of primitive types everywhere, so it is very much low-level like C, only with no tools that even plain old C offers, e.g. no true stack-allocated stru…

Fair point. The "with ease" part has also to do with Java's ecosystem. For instance, Martin Thompson used to teach people how to write a single-producer-multi-consumer queue. In a matter of hours, people can achieve 100M+ reads and writes on a 2014 MacBook Pro (I understand that throughput is different from latency, but given the fixed number of CPUs in this case, the latency of such implementation is also phenomenal…

Don't forget "chic" languages like Rust have the whole C ecosystem at their disposal.

Having done Java for many years and recently also done Rust, I'm not very convinced one ecosystem is richer than the other, when we talk about high performance computing. I've already hit a few things that are present in Rust I wished to have in Java. Generally I find the multithreading/concurrency libraries available in Rust very good.

Re: Data Race Patterns in Go

#174

Earlier quoted context omitted.

Fair point. The "with ease" part has also to do with Java's ecosystem. For instance, Martin Thompson used to teach people how to write a single-producer-multi-consumer queue. In a matter of hours, people can achieve 100M+ reads and writes on a 2014 MacBook Pro (I understand that throughput is different from latency, but given the fixed number of CPUs in this case, the latency of such implementation is also phenomenal…

Don't forget "chic" languages like Rust have the whole C ecosystem at their disposal. Having done Java for many years and recently also done Rust, I'm not very convinced one ecosystem is richer than the other, when we talk about high performance computing. I've already hit a few things that are present in Rust I wished to have in Java. Generally I find the multithreading/concurrency libraries available in Rust very g…

Definitely not everything or HPC. I was talking about building services that don’t need granular management of memory.

Re: Data Race Patterns in Go

#175
post #68

A dig against Rust I sometimes hear is "Oh, data race freedom isn't such a big deal, if you really need it, a garbage collected language like Java will give you that guarantee." So now I'm hearing that Go, a garbage collected language, doesn't guarantee data race freedom? I guess it's garbage collected but not "managed" by a runtime or something? Why go to all that effort to get off of C++ just to stop 30% short? The…

> Why do people keep adopting this language? Where's the appeal?

There're many aspects to consider when evaluating a tool. To me, Go has one of the best overall packages:

- std lib - tooling - performance - concurrency - relatively easy to get devs - reliable - mature

Also, Go has no substantial drawback. I personally consider an external runtime a drawback, for example.

I also use Rust personally. This discussion shows the value of Rust in terms of correctness. But for my professional projects Rust lacks the ecosystem guarantees that Go has with its great and useful standard lib. Looking at the Cargo dependencies of a mid size Rust web service is scary and reminds me of NPM. A large fraction of essential libs are maintained by a single person. Or unfortunately unmaintained. Rust with Go's std lib would be truly great.

Re: Data Race Patterns in Go

#176
post #109

Earlier quoted context omitted.

For me, Java and MySQL kind of died* when they became an Oracle thing. I just don’t want to go near anything that Oracle touches. The other thing is that I tend to write little programs where simple deployment on a low-resource machine is desirable. Go can handle that. Java kind of does the job with Graal now. The JVM is incredible, though, and I love Clojure. I’m hoping that Loom + Graal helps to kickstart more comp…

> For me, Java and MySQL kind of died* when they became an Oracle thing. I just don’t want to go near anything that Oracle touches. Come on, that’s a cheap reason (for Java, for open source db I would also go with postgre but for different reasons). Java is one of the very few languages with a full specification (not “whatever our compiler does, that’s the spec”), it has plenty of fully independent full implementatio…

Oracle has done great things for Java. The renewed investment over the past few years are bringing amazing things.

Re: Data Race Patterns in Go

#177

Earlier quoted context omitted.

> I never would've guessed that in 2022, Java would start looking more and more appealing in new ways. I don't quite understand the hatred (to the point of shouting "using Java? Over my dead body), especially in startups, towards Java. I mean, it's a language, big deal. Java's ecosystem more than enough offsets whatever inefficiencies in the language itself, at least for building many of the internal CRUD services. B…

I actually think the Java ecosystem is part of why people dislike it. Java seems to attract a lot of extremely heavyweight frameworks (like Spring) that are too complex to fully understand and too heavyweight to make sense for most projects.

So use helidon, micronaut, javalin, or spark if you want something small, but I suspect in any real application you’ll just end up recreating half of spring. That’s what my company did and it’s not near the quality of anything in Spring.

Re: Data Race Patterns in Go

#178

Earlier quoted context omitted.

Parent means var bestShape atomic.Value bestShape.Store((*Circle)(nil))

Which will store it as a *Circle, and only allow more *Circles, not Shapes. That part of GP’s claim is correct. It just had nothing to do with atomicity; it means something specific, not just “I like the failure mode.”

That's pretty easy to workaround:

    type shapeContainer struct { Shape }
The usual way to use atomic.Value is by writing strongly-typed wrappers anyway, so that doesn't affect your codebase beyond about 3 lines.

Re: Data Race Patterns in Go

#179
post #172

Earlier quoted context omitted.

I mean, Go clearly has goroutines as a “first class” concept for some value of “first class”, and (as they are a sort of thread) goroutines are concurrency. This is to say, I don’t think your claim about “must have async/await in order to have first class concurrency” is correct in any formal sense (maybe you’re defining “first class concurrency” as requiring async/await rather than asserting that this is what first-…

By that description though, Go also has first class types. And that kind of makes the distinction meaningless because essentially every programming language has types. There might be room to claim first-class support for green threads? But if so it's a very weak "first class" since all you can do is start them.

Yes, I think in the general sense of “first-class X”, “first-class types” would refer to any language with a concept of “type” (except perhaps certain dynamic languages where types are built from language primitives, but I’m not so sure about that case). I’m inclined to say that “first-class types” overrides that general formulation to mean “reified types” specifically. It’s also possible that I’m mistaken and the general formulation of “first-class X” always means exactly “reified X” (although I think reflection is a form of reification, and thus Go would have “first-class types” despite your above distinction between first-class types and reflected types), in which case Go doesn’t have “first-class goroutines”.

Re: Data Race Patterns in Go

#180
post #141

Earlier quoted context omitted.

What would you expect that code to do? I'd expect to have two different slices, s2 and s3, to contain all the same elements aside from the last. [a, b, c, x] and [a, b, c, y] and s1 remains [a, b, c]

When printing s1, s2, then s3: It does exactly that, yes: https://go.dev/play/p/rs2FeK_QUjs [a b c] [a b c x] [a b c y] But maybe it doesn't: https://go.dev/play/p/Na-eL0sOV9e [a b c] [a b c y] So... maybe they share the same backing array? Lets try setting s2[0] to "z" after appending with the original code: https://go.dev/play/p/mAB-gUb0shB [a b c] [z b c x] [a b c y] Apparently not. But also apparently yes? https:…

Is there a bug or issue on this in their GitHub cause wtf is this ?
Post reply on HN