-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement a new task spawning model not depending on a managed runtime #18000
Comments
Assigning P-backcompat-libs, not 1.0 milestone. (Also, there will be a forthcoming RFC regarding the relationship of stability markers and semver, which may illuminate some of the meta issues here...) |
Any reason tasks require a boxed closure? Is it just to prevent codegen bloat of having such a common function use generics? I'd be interested in spawning a task without the extra box. |
The overhead is insignificant due to the cost of making the stack allocation. It needs a to pass a function pointer and data parameter to a C function, and it needs to be bounded by |
See #18967 for some discussion on the thread semantics. This change is likely RFC-worthy. |
(I'm likely to prepare an RFC amendment to RFC 230, or perhaps a separate RFC on the threading API.) |
Also removes: * `std::task` * `std::rt::task` * `std::rt::thread` Notes for the new API are in a follow-up commit. Closes rust-lang#18000
This commit is part of a series that introduces a `std::thread` API to replace `std::task`. In the new API, `spawn` returns a `JoinGuard`, which by default will join the spawned thread when dropped. It can also be used to join explicitly at any time, returning the thread's result. Alternatively, the spawned thread can be explicitly detached (so no join takes place). As part of this change, Rust processes now terminate when the main thread exits, even if other detached threads are still running, moving Rust closer to standard threading models. This new behavior may break code that was relying on the previously implicit join-all. In addition to the above, the new thread API also offers some built-in support for building blocking abstractions in user space; see the module doc for details. Closes rust-lang#18000 [breaking-change]
This PR substantially narrows the notion of a "runtime" in Rust, and allows calling into Rust code directly without any setup or teardown. After this PR, the basic "runtime support" in Rust will consist of: * Unwinding and backtrace support * Stack guards Other support, such as helper threads for timers or the notion of a "current thread" are initialized automatically upon first use. When using Rust in an embedded context, it should now be possible to call a Rust function directly as a C function with absolutely no setup, though in that case panics will cause the process to abort. In this regard, the C/Rust interface will look much like the C/C++ interface. In more detail, this PR: * Merges `librustrt` back into `std::rt`, undoing the facade. While doing so, it removes a substantial amount of redundant functionality (such as mutexes defined in the `rt` module). Code using `librustrt` can now call into `std::rt` to e.g. start executing Rust code with unwinding support. * Allows all runtime data to be initialized lazily, including the "current thread", the "at_exit" infrastructure, and the "args" storage. * Deprecates and largely removes `std::task` along with the widespread requirement that there be a "current task" for many APIs in `std`. The entire task infrastructure is replaced with `std::thread`, which provides a more standard API for manipulating and creating native OS threads. In particular, it's possible to join on a created thread, and to get a handle to the currently-running thread. In addition, threads are equipped with some basic blocking support in the form of `park`/`unpark` operations (following a tradition in some OSes as well as the JVM). See the `std::thread` documentation for more details. * Channels are refactored to use a new internal blocking infrastructure that itself sits on top of `park`/`unpark`. One important change here is that a Rust program ends when its main thread does, following most threading models. On the other hand, threads will often be created with an RAII-style join handle that will re-institute blocking semantics naturally (and with finer control). This is very much a: [breaking-change] Closes #18000 r? @alexcrichton
Blocking threads on their children adds significant overhead and implies that Rust needs to be hosted in a runtime that's not compatible with the C model. Rust should be able to run on threads started from C without giving up the concurrency libraries. Higher-level abstractions can be built upon the primitives provided by the standard library, but it's not the place of the standard library to force subjective high-level design decisions with overhead onto applications.
The native model has both detached threads without the overhead of synchronization between the parent and child (as there is no hierarchy) and threads represented by objects that are joined in the destructor to avoid the need for additional synchronization primitives like channels in common cases. Rust needs to move to a model like this in order to complete the runtime removal RFC.
The API also uses
proc
, which is probably going to change before 1.0 because it will be replaced as as a distinct type byBox<FnOnce<...>>
. It might stay around as a form of sugar but marking any API using the old closures as stable is premature.The text was updated successfully, but these errors were encountered: