4 ms·
async/await is async io, this is something js is known for since it doesn't actually require parallelism. Getting concurrency _with_ parallelism right is a lot
by kpcyrd 7y ago
async/await is async io, this is something js is known for since it doesn't actually require parallelism.
Getting concurrency _with_ parallelism right is a lot easier in rust than it is in go. You need to write thread safe code in both of them, but you get zero support from your compiler in go.
- foldr 7y agoGo provides channels for safe communication between goroutines (which are distributed across multiple threads).
- twic 7y agoYou can use channels to pass mutable objects, which are then shared between threads. The passing itself may be safe, but the resulting situation isn't. The Rust compiler won't let you do that.
- the_duke 7y agoRust prevents data races with the `Send` and `Sync` markers, but that's a long way from making concurrency and parallelism easy. In Go, as long as you are not sharing data, you don't really have to care about whether something is concurrent or parallel, the runtime takes care of it for you. You just use goroutines, IO transparently happens on a dedicated threadpool, CPU heavy tasks are spread out over the available cores. As long as you restrict sharing to sending owned data over channels, you are mostly in the clear. Of course sometimes performance concerns etc mandate more traditional tools (atomics, mutexes, etc) and there the compiler won't help you anymore, but I'd argue that is the exception in Go rather than the norm. You can often solve problems with a actor-system inspired design. (learning Erlang/Elixir will probably make you a better Go developer!) In Rust, you still have to care a lot about what you do. Things like tokio::fs can handle file system IO for you, but you need to ensure that code you are calling does no synchronous IO. Also, CPU heavy workloads should be offloaded to a dedicated CPU thread pool, since the tokio runtime is not intended for juggling CPU intensive tasks in addition to the async IO. This is fine for Rust, a language that wants to give you insight and control, but it is still much more demanding of the developer.
- pcwalton 7y ago> You just use goroutines, IO transparently happens on a dedicated threadpool, CPU heavy tasks are spread out over the available cores. In Rust you can do that too! Just use threads. That's what Go does: it just uses threads. Async I/O is there if you need better performance than what Rust—or Go—can provide. If you don't need that performance, then don't use async I/O.
- foldr 7y agoGo uses async IO under the hood (for network IO at least). The exposed API is blocking, but the underlying implementation uses async IO and transparently schedules Goroutines across different OS threads. As you know, Rust doesn't currently have stable support for a similarly high-level interface to async IO. See e.g. the following reddit thread from 3 months ago: https://www.reddit.com/r/rust/comments/ausuld/what_is_the_current_state_of_async_io_in_rust/ https://www.reddit.com/r/rust/comments/ausuld/what_is_the_cu...
- pcwalton 7y agoUsing async I/O in userspace to implement the sync I/O interface of goroutines is equivalent to what the kernel does to implement sync I/O for normal threads.