5 ms·
This is something I learned through the course of trying to be clever in my early days of using Go (circa 2011) and it's something I wish my CS courses made exp
by mholt 7y ago
This is something I learned through the course of trying to be clever in my early days of using Go (circa 2011) and it's something I wish my CS courses made explicitly clear, and I think all programmers should at some point learn this difference. Even in JavaScript, race conditions are possible.
In fact, I'm pretty sure my car's "infotainment" system has several race conditions (though I'm not sure about data races specifically). After years of dealing with these kinds of bugs, you can smell them a mile away especially on software you use a lot. Symptoms: highly sporadic / unpredictable behavior of a wonky state machine. These are hard to document and debug!
My car, for example, will sometimes exhibit these behaviors:
- Volume changes Android Auto levels even though only music is playing
- Backup camera is not on anymore, but steering alignment overlay remains when side camera is activated
- Computer+screen stays on even though car is off
- Audio is quieted for a notification but then never returned to its previous volume
- Buttons change state as if the screen was showing something else
Race conditions are really common, I think. I know this is just my car as an example but you've probably experienced them on any moderately-complex systems you've used. I bet your TV has race conditions. And your router. And your ("smart") thermostat. I hope airplanes and spacecraft don't.
- 0815test 7y agoNot only that, but race conditions of this broad, "logic-related" sort are especially common in message-passing concurrency models, like the one that Go makes idiomatic. To make things worse, Go also has data races, when using plain old shared-access concurrency!
- masklinn 7y ago> To make things even worse, Go also has data races, when using plain old shared-access concurrency! And Go's message passing readily and silently devolves to unprotected shared-data concurrency as you can (and people commonly will either for performance reasons or because of reference types like maps or slices) send pointers through channels.
- knocte 7y ago> Even in JavaScript, race conditions are possible. I guess this was a joke/typo? Otherwise, are you implying that JS has any protection against them? This would be the last language I would think of.
- vitalus 7y agoI think that the "Even in JavaScript..." comment was written with the idea that race conditions might not be present/possible in single threaded environments, such as JavaScript...I read it as "Even in a single-threaded environment, such as JavaScript..." I don't think that most folks would hold up JS as some sort of gold standard of language design, and it doesn't seem that the author is doing so here.
- knocte 7y agoThat makes more sense.
- mntmoss 7y agoI have a little rant on this. In the scale of "understanding imperative semantics", awareness of race conditions is probably near the very high end of difficulty, while pointers are only somewhere in the middle. And that's a problem, because there are plenty of languages, JS included, that free you from understanding pointers while still making it very easy to create racy code. As such there are a lot of programmers going around with a false understanding of whether they are writing robust concurrent code - because they don't think it is concurrent. It doesn't say "concurrent" on it - this is a footgun naturally achieved with any sufficiently complex loop - and often they have made some effort to tuck away mutability in tiny functions, hindering efforts to find and fix the resulting race conditions.
- pdpi 7y agoInversely, it's relatively easy to abstract away the complexity of pointers (so we do), but useful abstractions that make race-y code impossible are horrendously hard to get right (so we don't). Rust's borrow checker is a great example of the sort of complexity you _have_ to bring in to have your language protect you from data races.
- zzzcpan 7y agoNone of those car examples are necessarily race conditions. Most of those are likely deterministic and merely the result of wrong assumptions due to poor understanding of the system about what happens on which event, i.e. your usual software development. Don't mistake that for race conditions! Just the other day I was working on a browser extension and saw some things not getting triggered sometimes, but since it's a single threaded event driven code in a single content script it can't really have race conditions, everything is deterministic, and it took only five minutes and couple of console.log()s to figure out what the problem was.