Live data from Hacker News

Concurrency in Rust

doc.rust-lang.org

101–110 of 160 posts

Re: Concurrency in Rust

#101

Earlier quoted context omitted.

This is an area where you just can't actually please everyone. I have heard the same opinions you've expressed in this thread, just as strongly, for even including unwinding at all. That aborts should be the only option, and that the cost of unwinding is far too high to be included in a true systems language. Language design is tough. I'm glad we have multiple languages.

It's _because_ Rust tried to please everyone that it painted itself into this corner. If the exception people had won, life would have been great. But if the error-code people had won, then life would still be good, because then Rust's stdlib might have been a bit uglier, but it would at least be correct with respect to error propagation. It's because Rust tries to satisfy both camps --- because it tries to give you…

I prefer "taking all use-cases seriously instead of abandoning a segment of users" to "happiness and harmony," as a characterization here. If serious use cases were not presented for both options, we would have enforced one. Or, if Rus weren't a systems language, we could have enforced one.

At the end of the day, if you have exceptions, you can still call abort in your exception handlers, so the split exists regardless. And without first-class support, those users are paying for a feature that they aren't using, which is against a core value of Rust.

Re: Concurrency in Rust

#102
post #87

Earlier quoted context omitted.

Exceptions can be turned into aborts in C++ as well, and are in many types of programs, because exceptions do have downsides for some problem domains. If Rust forced exceptions on everyone, there'd be people complaining about that just like you're complaining now. I see the split between `Result` and `panic!` as more like Java's split between checked and runtime exceptions, except `Result` is much more usable than ch…

> Exceptions can be turned into aborts in C++ as well, No you can't. -fno-exceptions does not appear in the C++ standard. You can write a compiler for any language. C++-that-aborts-on-throw is not C++, although, sure, it's closely related. The ability to turn off C++ exceptions was a temporary workaround for compiler deficiencies in the 1990s that snowballed into an extremely harmful schism that's still doing tremend…

That's not a very meaningful distinction to make- Rust doesn't even have a standard right now. Besides, -fno-exceptions is quite useful today, not just because of 90s compiler deficiencies, and is pretty well-supported by compilers.

Re: Concurrency in Rust

#103

Send + Sync are great. The downside of concurrency in Rust is: 1) There isn't transparent integration with IO in the runtime as in Go or Haskell. Rust probably won't ever do this because although such a model scales well in general, it does create overhead and a runtime. 2) OS threads are difficult to work with compared to a nice M:N threading abstraction (which again are the default in Go or Haskell). OS threads lea…

> 1) There isn't transparent integration with IO in the runtime as in Go or Haskell. Rust probably won't ever do this because although such a model scales well in general, it does create overhead and a runtime.

By "transparent integration with the runtime" you mean M:N threading. M:N threading is just delegating work to userspace that the kernel is already doing. There can be valid reasons for doing it, but M:N threading isn't us not doing the work that we could have done. In fact, we had M:N threading for a long time and went to great pains to remove it.

In addition to the downsides you mentioned, M:N threading interacts poorly with C libraries, and stack allocation becomes a major problem without a precise GC to be able to relocate stacks with.

M:N will never be as fast as an optimized async/await implementation can be, anyway. There is no way to reach nginx levels of performance with stackful coroutines.

> OS threads leads to lowest common denominator APIs (there is no way to kill a thread in Rust)

This has nothing to do with the reason why you can't kill threads in Rust. We could expose pthread_kill()/pthread_cancel() on Unix and TerminateThread() on Windows if we wanted to. The reason why you can't terminate threads that way is that there's no good reason to: if you have any locks anywhere then it's an unsafe operation.

> some difficulty in reasoning about performance implications.

I would actually expect the opposite to be true: 1:1 is easier to reason about in performance, because there are fewer magic runtime features like moving or segmented stacks involved. Could you elaborate?

Re: Concurrency in Rust

#104
post #97

Earlier quoted context omitted.

Even C++ doesn't have mandatory exception support, and even Rust can catch panics from failure-oblivious code.

> Even C++ doesn't have mandatory exception support Yes it does. That some compilers provide a way to disable mandatory language features is no argument. > even Rust can catch panics from failure-oblivious code. Not while maintaining that code's invariants it can't.

Are you saying C++ make it easy to write exception-safe code? Because Rust explicitly encodes exception safety into the type system with the RecoverySafe trait, you need to write unsafe code to bypass that, and the documentation on unsafe explicitly covers exception safety.

Re: Concurrency in Rust

#105
post #102

Earlier quoted context omitted.

> Exceptions can be turned into aborts in C++ as well, No you can't. -fno-exceptions does not appear in the C++ standard. You can write a compiler for any language. C++-that-aborts-on-throw is not C++, although, sure, it's closely related. The ability to turn off C++ exceptions was a temporary workaround for compiler deficiencies in the 1990s that snowballed into an extremely harmful schism that's still doing tremend…

That's not a very meaningful distinction to make- Rust doesn't even have a standard right now. Besides, -fno-exceptions is quite useful today, not just because of 90s compiler deficiencies, and is pretty well-supported by compilers.

The existence of -fno-exceptions means that library authors either using the language as intended, and accept losing a portion of their potential user base, or write less-than-optimally elegant and clear code, which punishes everyone, so a few can turn off a core feature of the language. It fragments the community.

Re: Concurrency in Rust

#106
post #104

Earlier quoted context omitted.

> Even C++ doesn't have mandatory exception support Yes it does. That some compilers provide a way to disable mandatory language features is no argument. > even Rust can catch panics from failure-oblivious code. Not while maintaining that code's invariants it can't.

Are you saying C++ make it easy to write exception-safe code? Because Rust explicitly encodes exception safety into the type system with the RecoverySafe trait, you need to write unsafe code to bypass that, and the documentation on unsafe explicitly covers exception safety.

Rust's type system doesn't attempt to guard against resource leaks.

Re: Concurrency in Rust

#107
post #104

Earlier quoted context omitted.

Are you saying C++ make it easy to write exception-safe code? Because Rust explicitly encodes exception safety into the type system with the RecoverySafe trait, you need to write unsafe code to bypass that, and the documentation on unsafe explicitly covers exception safety.

Rust's type system doesn't attempt to guard against resource leaks.

It doesn't guarantee destructors will run, that's true, but that's for things like Rc cycles. Take a look at the RFC for std::panic::recover- it definitely takes exception safety into account: https://github.com/rust-lang/rfcs/blob/master/text/1236-stab...

Also take a look at things like the design of the Drain iterator- the stdlib is definitely (intended to be) exception safe.

Re: Concurrency in Rust

#108
post #59

Earlier quoted context omitted.

I am in the middle of working on a second draft of the book. This page is one of the oldest bits of docs, overall, and isn't my best work. It's not _wrong_, I just have very high personal standards. It was adapted from older documentation and was written in the time up to 1.0, where I had a LOT on my plate.

It certainly is _confusing_ if not _wrong_. You silently add "move" to the closure without any mention or explanation (then later say "note that we're copying i" without explaining that you're talking about the "move" keyword). The bit about Mutex also has a "just type this to fix the problem with no explanation of how or why it works" flavour (although I guess if you already grok mutexes then its use here might be o…

> what this message that doesn't mention Sync is trying to tell you is that you need Sync on this type

There's no such error message that I'm aware of.

Re: Concurrency in Rust

#109

Earlier quoted context omitted.

A failed malloc aborts the process. If this is important to you, don't use the heap abstractions in the stdlib then. This is no different from the situation in C++. (You can also plug in a custom allocator which behaves differently)

No custom allocator can make a task that fails to allocate gracefully report an error. Rust's error handling design is just terrible, and mostly a consequence of eschewing exceptions. Had Rust opted for exceptions, it'd be a much better, and actually usable, language. Rust's terribly error-handling strategy is the chief reason not to use it.

> No custom allocator can make a task that fails to allocate gracefully report an error.

Yes, you can. You can panic the thread, and you can recover from panics. But honestly this is never enough to gracefully recover from OOM. I can't think of any software that uses exceptions to gracefully recover from OOM (i.e. without crashing the process) in a way that works. How many Java applications do you see that catch OutOfMemoryError on a fine-grained level?

> Had Rust opted for exceptions, it'd be a much better, and actually usable, language. Rust's terribly error-handling strategy is the chief reason not to use it.

It's hyperbolic to call Rust's error handling strategy not "actually usable". I use it every day and never have any issues with it.

Re: Concurrency in Rust

#110

Earlier quoted context omitted.

> and mostly a consequence of eschewing exceptions. A panic is the same thing as an exception. If you want to catch a panic, use recover(), it's meant to be used exactly for these end-of-the-world panic scenarios (and for FFI/etc). You can plug in a custom allocator that panics on OOM (I think the standard one aborts). As Steve mentioned, custom allocators can mean two things. The type that exists in rust today is on…

> A planned extension will let you have allocators with different semantics entirely work with stdlib types And what about all the code that doesn't? It's because so much code exists that's completely oblivious to the possibility of these stdlib functions failing that I don't think that merely adding the option to do the right thing is good enough. The existing failure-oblivious APIs need to be explicitly deprecated.…

> The existing failure-oblivious APIs need to be explicitly deprecated.

That's total overkill. For 99% of applications, process abort is fine, and dealing with it is just noise. Those 1% are usually things like kernels that use custom standard libraries anyway.

We're not doing the 99% a favor by making them think about OOM every time they do something that might allocate.

> The only ways to redeem Rust is to either support exceptions as first-class citizens with mandatory runtime support or to convert all existing allocating stdlib functions to return Result and mark all the existing failure-oblivious ones as being as deprecated as gets(3) in C.

This is silly hyperbole. Ask anyone who works in security whether the danger of xmalloc() is comparable to the danger of gets(). In fact, I've seen many security folks recommend only using xmalloc() with process abort instead of trying to explicitly handle OOM failures!

Post reply on HN