5 ms·
Putting the word "semantically" in front of deadlock doesn't change its meaning: https://en.wikipedia.org/wiki/Deadlock https://en.wikipedia.org/wiki/Deadlock
by acconsta 11y ago
Putting the word "semantically" in front of deadlock doesn't change its meaning:
https://en.wikipedia.org/wiki/Deadlock https://en.wikipedia.org/wiki/Deadlock
Either way, redefining the word does nothing to make mutexes and native threads safer or easier to use in practice.
I can't emphasize this enough — data races are not the only kind of concurrent programming error, yet they are the only kind prevented by borrow checking. Go, Erlang, and Node have high level approaches to concurrency that reduce other categories of errors (in addition to providing massive performance benefits vs. naive native threading).
I think the time to add good concurrency abstractions to a language is before 1.0, but I'm in strong disagreement with the community there. And judging by this thread, concurrent IO isn't even on the core team's roadmap. This is not a good sign for a language that sells itself on concurrency!
Look at the situation 10 months ago. How much has it improved?
https://www.reddit.com/r/rust/comments/2l0a4b/do_rust_web_servers_use_libuv_through_libgreen_or/ https://www.reddit.com/r/rust/comments/2l0a4b/do_rust_web_se...
Channels are a step in the right direction, but are pretty limited without coroutines (channels without coroutines are just synchronized queues). Atomics are cool, but they address a totally different problem. Reagents, well, let's see an implementation.
C++ has needed a successor for many years now, and Rust is the best candidate. But lofty claims notwithstanding, the Rust concurrency situation is pretty dreadful.
- dbaupp 11y ago> Putting the word "semantically" in front of deadlock doesn't change its meaning: And focusing on hangs in concurrent programs that are caused by using a data structure called "mutex" doesn't stop one getting exactly the same symptoms via your apparently-perfect channels. One can use channels to get all four of the conditions required for a deadlock, especially Go's synchronous-by-default channels. Any time you have a protocol of multiple tasks communicating with each other in some structured way, it's possible to break that protocol and hence have tasks sitting around waiting for messages that aren't coming. Especially in languages like Go/JavaScript/... which aren't powerful enough to model things like session types in their type system, e.g. https://www.reddit.com/r/rust/comments/3jhd56/session_types_safe_internal_communication/ https://www.reddit.com/r/rust/comments/3jhd56/session_types_... > I can't emphasize this enough — data races are not the only kind of concurrent programming error, yet they are the only kind prevented by borrow checking Yes, that's exactly why the whole Rust community tries to be very careful about using "data race" when talking about concurrency in Rust. However, it is the case that data races are the worst sort of concurrency bug: they are undefined behaviour and so can lead to arbitrary memory corruption, possibly only appearing a long way from the actual place with UB. Deadlocks and other problems are, by default, much more controlled in their failure modes. Rust focuses on truly outlawing large classes of horrible problems: dangling pointers, iterator invalidation, data races (and all without requiring a garbage collector, although a GC barely helps with the latter two). It also tries to help with other problems with fewer guarantees, but even just being memory safe is a huge step up from widely used low-level languages (i.e. C/C++). All the languages you mention are quite opinionated in their concurrency, imposing costs that Rust doesn't and can't, for its target space. (And, Go certainly doesn't provide any guarantees at all, not even data race freedom.) > in addition to providing massive performance benefits vs. naive native threading Important qualification: for IO bound tasks. Which is perfectly fine, but it needs to be understood. > I think the time to add good concurrency abstractions to a language is before 1.0, but I'm in strong disagreement with the community there What's so important about being pre-1.0? You seem focused on it, but I don't understand why. What benefit does Rust gain by delaying the release of 1.0 for months/years just to get good async IO support? Why is this particular pet feature any more important than everyone else's pet feature? (There have been so many requests: "why couldn't X make it into 1.0?") If you're concerned about theoretical fragmentation of the ecosystem... that's not a problem in practice: mio is the standard. > And judging by this thread, concurrent IO isn't even on the core team's roadmap Wrong, it's very much on the roadmap, e.g. Alex Crichton (core team member) has been adding windows support to mio himself. > Look at the situation 10 months ago. How much has it improved? A lot. There's a burgeoning ecosystem built around mio. --- In any case, Rust has been stable for barely 3 months. Be patient, and give it time for the concurrency story to blossom from the seeds that have been sown so far. Based on the experience so far, I'm pretty confident that Rust can easily be much better (i.e. more performant and reliable) than both Node and Go and even Erlang. (Of course, it may be syntactically less nice, since those languages bake it in deeply, while Rust is less opinionated.)
- acconsta 11y ago>your apparently-perfect channels I've never used Go, but it has some interesting concurrency ideas. So do Node and Erlang. I naively expect Rust to adopt the best ideas from each. >One can use channels to get all four of the conditions required for a deadlock, especially Go's synchronous-by-default channels. One can, yes. But it's pretty easy to avoid cyclic locking patterns when each request is handled by a separate goroutine, as is idiomatic. One thread per request in Rust will drag pretty quickly. Yes, the borrow checker is an impressive achievement. But is it enough for Rust to succeed? Marketing yourself as safer C++ is what Java already did (with tremendous success) 20 years ago. And the market for systems languages has only shrunk since then (my phone runs Java). >All the languages you mention are quite opinionated in their concurrency, imposing costs that Rust doesn't and can't, for its target space. And yet Rust has already partially standardized channels. Finish the channels, add coroutines and you've implemented Go! (I'll note there are already coroutine implementations for C and C++, which do not limit their use as systems languages). >(And, Go certainly doesn't provide any guarantees at all, not even data race freedom.) Which, interestingly, hasn't hindered its ability to become a successful language! A lesson worth remembering. >Wrong, it's very much on the roadmap, e.g. Alex Crichton (core team member) has been adding windows support to mio himself. I mean... https://github.com/carllerche/mio/graphs/contributors?from=2015-05-15&to=2015-09-09&type=a https://github.com/carllerche/mio/graphs/contributors?from=2... Could be worse, could be better? >Why is this particular pet feature any more important than everyone else's pet feature? I don't think "good concurrency is a pet feature" is the winning argument here. >I'm pretty confident that Rust can easily be much better (i.e. more performant and reliable) than both Node and Go and even Erlang. Me too! But I'm not sure that's going to happen with a single core developer on Mio and no timeline for standardization.
- kibwen 11y ago> I've never used Go, but it has some interesting > concurrency ideas. So do Node and Erlang. I naively > expect Rust to adopt the best ideas from each. This is where your naivete shows. Rust originally did have the same thread model as Go baked into the language and standard library, and it labored for years to find a usable compromise between Go's green thread model and the native threading model. And a compromise is indeed necessary, firstly because we don't just need another Go, and secondly because Go's threading model imposes horrific costs when trying to interoperate with non-Go code (literally thousands of times the overhead that you'd expect). For a language like Rust that intends to interoperate with the native ecosystem, that overhead is unacceptable. After about three or four complete redesigns and rewrites the entire green threading infrastructure was chucked to the curb. Fortunately, Rust is low-level enough that libraries like mio can pick up the slack on their own, and in the meantime libraries that don't need green threads don't have to pay the price.