Earlier quoted context omitted.
Yes. In Erlang: exit(kill). or exit(Pid,kill). Will kill a process. It has an isolated heap, so it won't affect other (possibly hundreds of thousands of) running processes. That memory will be garbage collected, safely and efficiently. This will also work in Elixir, LFE and other languages running on the BEAM VM platform. EDIT: masklinn user below pointed out correctly, the example is exit/2, that is exit(Pid,kill).…
This is called from within a threads execution, right? I think the question is about being able to kill a thread externally. Java had this in 1.0 or 1.1 and then thought better of it and deprecated the API.
Concurrency in Rust
141–150 of 160 posts
Re: Concurrency in Rust
#142Earlier quoted context omitted.
Besides, if you make exception-safe code difficult to write, nobody in practice will write it, so you'll end up with a system that's tantamount to one that just aborts. Saying that "Rust the language handled OOM just fine without stdlib!" and "we can convert OOM to panic!" is useless when these measures don't help real world code. I'm not sure where you get the "difficult to write" part from. It's no more or less dif…
There's more to the world than end-user applications though. I think your mental model is that there are two kinds of Rust user: OS kernel writers and people who create applications with menu bars and save buttons. What about network services that would rather begin failing requests on overload than shut down entirely and restart, incurring potentially big delays in the process? What about scientific computing projec…
There's more to the world than end-user applications
though. I think your mental model is that there are two
kinds of Rust user: OS kernel writers and people who
create applications with menu bars and save buttons.
Not at all. I myself work with more types of applications than that; I work with high-reliability networked daemons, GUI applications, and web applications. What about network services that would rather begin
failing requests on overload than shut down entirely and
restart, incurring potentially big delays in the
process?
High reliability network services generally need to be distributed across multiple machines anyhow, to provide reliability against the machine going down, so they have some notion of processes that can be stopped without shutting the whole system down. If your system can't handle one of the daemons being restarted, then it has bigger problems.However, even for this case, you can handle OOM more gracefully if you change allocation failure to panic rather than abort (either by changing the default in Rust's standard library, or using a custom allocator). At that point, you can define a proper task boundary on which you catch unwinding, make sure that everything shared across that task boundary is exception safe, and recover gracefully.
What about scientific computing projects that
are happy delaying work once they've hit pre-defined
limits? I think you're suffering from a failure of
imagination.
How many of these applications use malloc failure as their backpressure mechanism against over-allocation of resources? In general, I think they have a tendency to distribute small jobs across a large cluster, balancing them based on resource utilization, and accepting that some jobs may fail for various reasons with the ability to re-run said jobs if necessary. If Rust's goal is to supplant C, it needs to be capable
of everything C is capable of doing. Arguing that
applications in general need X or Y is a canard, because
most of those applications have no specific need of the
kind of direct memory control that Rust affords.
Rust's goal is not necessarily to supplant C or C++; they are far too widely used for that ever to be realistic.The goal is to provide a reasonable, safe alternative, that offers better abstractions and greater safety, and can be used in situations that other high-level safe languages are unsuitable for.
As far as replacing C, Rust absolutely is capable of replacing C; just use #![no_core] and handle allocation failure however you want. C++'s standard library is more comparable to Rust's standard library.
To put it another way: who are you trying to satisfy? Are
you trying to compete with Go, Nim, Python, and Java and
provide high-level facilities that work most of the time,
at the cost of control, or are you trying to compete with
C and C++, which still fill an essential niche?
By appealing to arguments about the requirements of
applications in general instead of requirements of
systems programming languages specifically, you're
suggesting that the former audience is the better bet.
As an aside, when you say "you", it sounds like you may be addressing me as a member of the Rust team. I am not; I am a user of Rust, and have contributed a few small patches, but I am only speaking for myself and not anyone else.Rust is a general purpose programming language, that is designed to appeal to a wide audience, but fill needs that other high-level languages cannot, and provide safety and abstraction that C or C++ cannot.
The first audience is likely a much larger audience, and so it is worth keeping their needs in mind, while the second audience can take the most advantage of Rust's safety and performance guarantees.
That kind of targeting is sad, since one of the promises
of Rust is that its memory safety would save us from the
plague of security holes in low-level software. The
decisions the Rust project is making right now make it
less likely that Rust will be able to fully fill C and
C++'s niche.
There are many, many applications, including more than just GUI facing applications but also servers, high-performance computing, etc, written in C and C++ that do not, and do not or do not need to handle allocation failure explicitly. In fact, in this entire discussion, you still have not pointed to a single example of a C++ application that does anything other than abort on allocation failure.However, even for applications that do not need to handle allocation failure, they would be able to take advantage of type safety, memory safety, and easy, safe concurrency. You are focusing on one, small issue, and ignoring the huge swath of other issues that you run into when writing C or C++ code that can go away by using Rust.
One of the purposes of having a standard library for a
project is to be a universal resource for all users of a
language. If Rust's standard library isn't suitable for
all environments where Rust might be used (like C++'s
standard library is), then maybe it should be packaged as
a separate project, like Qt.
But C++'s standard library is not suitable for all environments in which it's used. Other examples that have already been brought up in this discussion are in kernels, embedded systems, in any code running at Google, and heck, as you mention there are third-party libraries like Qt that are widely used frequently to the exclusion of the standard library.Something like C++ or Rust's standard library cannot be used in all situations, and even in places where it could run, no general purpose standard library is ever going to satisfy all users. What Rust aims to provide is one that works best, and most naturally, for a wide variety of use cases, which includes GUI applications, web apps, network daemons, and scientific application.
Since handling allocation failure as anything but an abort is so uncommon, it chooses to avoid either of the other two options: requiring everything that allocates to return a Result, making the interfaces to every collection type much more painful to use, or having pervasive exceptions and exception handling, meaning you need to think about exception safety everywhere.
The approach that Rust takes is a moderate approach; it uses return values for those errors that pretty much any user will have to handle, and panics for truly exceptional situations that normally should lead to an abort but which you can add special handling for at task boundaries if you need to provide higher availability, which means that you limit the number of places in which exception-safety needs to be considered to just those boundaries.
At the moment, it uses aborts for allocation failure, but there's nothing inherent to the language about that, just the current implementation.
I think the main point where our opinions diverge is that I see handling memory allocation failure with anything other than an abort as much, much more rare than the extremely common cases of exceptional situations leading to much worse results in C or C++. The sheer amount of undefined behavior, the mysterious bugs caused by buffer overruns overwriting random bits of the stack, the security vulnerabilities, the bugs caused by some undefined behavior you didn't realize was there causing the optimizer do do something strange to your code, and so on.
If allocation failure causing an abort when pushing to a Vec, unless you supply a custom allocater that panics instead and implement proper panic handling, is something that you think is fatal in terms of choosing a language, why is it not fatal that one single missed buffer length check buried in one library somewhere can cause completely unrelated parts of your application to fail mysteriously? As far as appropriateness for the kinds of projects you describe, other than the greater library and tool support due to being much more mature ecosystems, I can think of very few cases in which C or C++ would be preferable to Rust; so much of their behavior on unexpected situations is so much worse than an abort.
Re: Concurrency in Rust
#143Earlier quoted context omitted.
> Rust's notoriously poor error messages I've actually heard the opposite feedback; Rust's error messages try to be super helpful. Note that concepts like ownership and Sync are new to most programmers, and it's impossible to explain them in an error message. This is where the extended error messages (via --explain) and the book come in. The tutorial has this style because Rust espouses catching things at compile tim…
I've found the Rust compiler to provide very useful messages. That said, it does take a certain amount of experience in the language before you grok the terminology and appropriate remedies to overcome some compiler errors. As a beginner, I'd typically open about 5-10 different documentation, blog post, SO and tutorial pages to try to figure out what I was doing wrong. Once I understood the underlying concept, I coul…
I love the extended errors. Note that you can just use `rustc --explain ` without opening a web page, but of course it won't be formatted then.
> But it takes time if you're coming from a non C/C++ language!
Ultimately there's little substitute to learning the concepts behind the language :) Error-driven-development is fun, and quite useful once you know the language, but if used as the only way to learn the language it can be problematic. That said, I enjoy using errors to explain Rust concepts -- as long as you explain them. If a new user is hit with a steaming pile of errors you can't really expect them to understand it directly.
I have talked with a lot of folks coming from a non-systemsy background, and sort of have an idea of the things that get confusing (I once had similar problems when learning C++). I'm planning a blog post series (no ETA, pretty swamped with other work :/ ) that teaches both Rust (specifically, the safety bits like the borrow checker) and what's going on under the hood (regarding memory, the stack/heap, etc) using each as a crutch to explain the other in a leapfrog way, to introduce the language and low-level programming to folks coming from languages like JS.
Re: Concurrency in Rust
#144Earlier quoted context omitted.
There's more to the world than end-user applications though. I think your mental model is that there are two kinds of Rust user: OS kernel writers and people who create applications with menu bars and save buttons. What about network services that would rather begin failing requests on overload than shut down entirely and restart, incurring potentially big delays in the process? What about scientific computing projec…
> If Rust's goal is to supplant C, it needs to be capable of everything C is capable of doing. We have demonstrated this multiple times. You can either use your own stdlib like sqlite, or use recover. You may not like the solution, but the fact still remains that it still is a tangible solution (well, the latter one is -- "your own stdlib" is a pretty specialized solution which you shouldn't need) to the problem. Giv…
> Please stop ignoring the fact that Rust does have a solution to the OOM problem;
I disagree that what you're calling a solution is, in fact, a solution. It's more like defining away the problem. It's the case that most Rust programs, those that use stdlib, will never be able to rigorously respond to all allocation failures.
You don't get to wave away problems with Rust stdlib with appeals to an unhosted environment when C++'s stdlib doesn't have the problems I'm highlighting. There's no reason std::vector couldn't be used in a kernel --- just no history.
The SQLite criticism is not the point. The request was for a tested component that recovers from allocation failure. Now you're saying that this example isn't good enough because it's written in C. You're moving the goalposts.
I've already outlined what it would take for me to agree that Rust's OOM problem is solved. It looks like Rust is just adding a few ways of optionally doing more stringent checks, not actually propagating failure from core routines appropriately.
> Not necessarily. The former audience encompasses the latter. Rust doesn't want to put undue burden on general users (like having to check all allocations or having to think about exception safety)
Should these poor users get a pony too? Programming is about managing resources. I've outlined elsewhere the kind of trap you force yourself into when you simultaneously avoid both exceptions and error codes. By doing both, you're not making the world a simpler case. You're just hiding the nasty bits that can go wrong, and users deserve better.
Re: Concurrency in Rust
#145Earlier quoted context omitted.
> If Rust's goal is to supplant C, it needs to be capable of everything C is capable of doing. We have demonstrated this multiple times. You can either use your own stdlib like sqlite, or use recover. You may not like the solution, but the fact still remains that it still is a tangible solution (well, the latter one is -- "your own stdlib" is a pretty specialized solution which you shouldn't need) to the problem. Giv…
You haven't changed my mind about Rust being unfit for purpose. > Please stop ignoring the fact that Rust does have a solution to the OOM problem; I disagree that what you're calling a solution is, in fact, a solution. It's more like defining away the problem. It's the case that most Rust programs, those that use stdlib, will never be able to rigorously respond to all allocation failures. You don't get to wave away p…
I'm not talking about using a different stdlib, I'm talking about recover().
> You don't get to wave away problems with Rust stdlib with appeals to an unhosted environment when C++'s stdlib doesn't have the problems I'm highlighting.
I didn't do that. I'm asserting that Rust's stdlib is appropriate for more or less all situations where you would use C++s stdlib. I have already explained why recover() should be adequate when you want to handle OOM, and recover() is part of the regular stdlib.
I was just putting the raison d'etre for no_std out there, and noting that the situations where you would use it in Rust exist in C++ too. I was trying to dispel the argument that "no_std exists in Rust, hence the stdlib isn't appropriate for all use cases, hence it shouldn't be part of the distribution", which you might have been making in the grandparent comment (I'm not sure if you were).
> The SQLite criticism is not the point. The request was for a tested component that recovers from allocation failure. Now you're saying that this example isn't good enough because it's written in C. You're moving the goalposts.
Fair. I'm not the one who made the original request, so I forgot about that.
> It looks like Rust is just adding a few ways of optionally doing more stringent checks, not actually propagating failure from core routines appropriately.
I'm not sure what you mean here.
Rust already has the ability to catch all panics and handle OOMs at an abstraction boundary of your choice as a global solution, similar to exceptions in C++.
Rust is getting the ability to do fine-grained C-like (or "C++ with try/catch around every `new`" -like) allocation failure handling in custom allocators v2, which can also tie in with your regular error propagation machinery.
> I've already outlined what it would take for me to agree that Rust's OOM problem is solved.
You really haven't. You've just attacked Rust's lack of exceptions incessantly without much arguments to back it up. You've not mentioned why recover() (given that it has exception safety built in and exception safety was a first-class concern during its design) is inadequate.
> you simultaneously avoid both exceptions and error codes.
Rust's Result type is basically a safer and more robust error code. Custom allocators v2 gets you error-code-like allocation that can tie in with your regular error handling.
(FWIW you can do errno-like error handling of OOM using the current support for custom allocators already, though making this safe might be tricky)
Re: Concurrency in Rust
#146I think Steve Klabnik could clarify this, but the book at that link is in the process of being rewritten. I think it might be good to wait until it is. I personally found it slightly difficult to follow compared to other options like the soon to be published Programming Rust.
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.
Re: Concurrency in Rust
#147Earlier quoted context omitted.
While quotemstr's reaction is over the top, I do see the need to have a memory allocation approach that can handle OOM gracefully. Many types of software that could benefit from Rust's compile-time safety will want to allocate right up to the limit of available memory, such as audio/video processing software where more memory equals more simultaneous effects and less I/O. I am endlessly frustrated by poorly designed…
> I do see the need to have a memory allocation approach that can handle OOM gracefully. Do you find anything wrong with inserting an allocator that panics on OOM (IIRC the default one aborts on OOM) and using `std::panic::recover` to catch the panic? This is the same as throwing and catching an exception. Note that `recover()` is designed to be exception safe by default. (There soon will be a way to make std heap AP…
Re: Concurrency in Rust
#148Earlier quoted context omitted.
This is called from within a threads execution, right? I think the question is about being able to kill a thread externally. Java had this in 1.0 or 1.1 and then thought better of it and deprecated the API.
It works correctly either way -- externally with exit(Pid,kill) or by the process itself as exit(kill). The last one is just a shorthand for exit(self(), kill). Where self() is the process id of the currently running process.
But the way you showed was not one in which anyone was interested, synchronous exceptions work in more or less every language, and you can't assume readers know your self-killing is actually implemented via asynchronous exceptions since they don't know the language.
Re: Concurrency in Rust
#149Earlier 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…
Re: Concurrency in Rust
#150Earlier quoted context omitted.
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…
You are arguing for replacing bad behavior "abort on OOM" with something even worse, exceptions. I honestly don't think you know what exceptions entail wrt what compilers do and the resulting bloat.