4 ms·
> If you use Tokio's single-threaded runtime, things get simpler. I don't do a lot of low level work, but coming out of Elixir / Erlang I would expect a greenl
by aeturnum 3y ago
> If you use Tokio's single-threaded runtime, things get simpler.
I don't do a lot of low level work, but coming out of Elixir / Erlang I would expect a greenlet system to manage the # of threads based on the hardware its running on. I.e. not single threaded or "you manage the threads too" but "a standard piece of code spreads your greenlet processes between N managed hardware threads where N is determined by hardware + settings." Is that not a thing that the Rust async libraries support?
- watermelon0 3y agoBy default, Tokio uses multi-threaded runtime, but you can force it to use the single-threaded one: https://docs.rs/tokio/latest/tokio/attr.main.html#current-thread-runtime https://docs.rs/tokio/latest/tokio/attr.main.html#current-th...
- ekidd 3y agoElixir/Erlang is actually a really interesting case, because: 1. It has a garbage collector, and 2. It relies even more heavily on immutable data than Rust. This means that the Beam VM can seamlessly move green threads around CPUs and preempt them at arbitrary points, all without breaking code. You never need to know who "owns" something, and you never need to worry about another process mutating it while you're looking at it. The Beam VM is amazing. Tokio operates under different constraints: There's no garbage collector, ownership can be "lent" to other code, and mutable state exists in a carefully controlled fashion. Despite this, Tokio absolutely supports spreading green threads across all your CPUs and moving them as needed using a work-stealing scheduler (IIRC). But this only works if all your closures are `Send` (safe to move between CPUs). And any closure that outlives the creating code must generally be `'static` (it does not refer to references borrowed from its creator's scope). Oh, and Rust keeps trying create and manage your async & multithreaded processes without trying to allocate heap memory at all. Unless you explicitly ask it to allocate memory. Which you often should. It is totally possible to make your closures `Send + 'static`. I maintain several production Rust programs which do that, no problem. But doing so requires understanding a moderate amount of Rust and paying a "cognitive tax" by making a bunch of extra decisions about how to represent things. And I think that cognitive tax is a unwise tradeoff for many problems and teams. But I'm still very happy with my async Rust projects, because they get a lot of value out of fast, memory-efficient async code.
- aeturnum 3y agoThat makes a lot of sense! I guess I was imagining that a greenlet system would have a kind of 'light vm' by default, but you're absolutely right that the constraints of Erlang make that a LOT easier in their VM. I wasn't really thinking about the the locality difficulties of managing process resources (or I guess I was imagining that the meta-info collected by Rust would help but I guess it's mostly not runtime).