cometyang / rust-concurrency

Rust Concurrency Cheat Sheet

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Rust Concurrency Cheat Sheet

Safety

Rust ensures data race safety through the type system (Send and Sync marker traits) as well as the ownership and borrowing rules: it is not allowed to alias a mutable reference, so it is not possible to perform a data race.

Overview

  Problem
Parallelism Multi-core utilization
Concurrency Single-core idleness
  Solution Primitive Type Description Examples
Parallelism Multithreading Thread T: Send Do work simultaneously on different threads std::thread::spawn
Concurrency Single-threaded concurrency Future Future Futures run concurrently on the same thread futures::future::join, futures::join
Concurrency
+Parallelism
Multithreaded concurrency Task T: Future + Send Tasks run concurrently to other tasks; the task may run on the current thread, or it may be sent to a different thread async_std::task::spawn, tokio::spawn

Futures

pub trait Future {
    type Output;
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

pub enum Poll<T> {
    Ready(T),
    Pending,
}
  • Future has to be polled (by the executor) to resume where it last yielded and make progress (async is lazy)
  • &mut Self contains state (state machine)
  • Pin the memory location because the future contains self-referential data
  • Context contains the Waker to notify the executor that progress can be made
  • async/await on futures is implemented by generators
  • async fn and async blocks return impl Future<Output = T>
  • calling .await attempts to resolve the Future: if the Future is blocked, it yields control; if progress can be made, the Future resumes

Futures form a tree of futures. The leaf futures commmunicate with the executor. The root future of a tree is called a task.

Share state

  Threads Tasks
channel std::sync::mpsc (Send), crossbeam::channel (Send, Sync) tokio::sync::mpsc, tokio::sync::oneshot, tokio::sync::broadcast, tokio::sync::watch, async_channel::unbounded, async_channel::bounded
mutex std::sync::Mutex tokio::sync::Mutex

Marker traits

  • Send: safe to send it to another thread
  • Sync: safe to share between threads
Type Send Sync
Rc<T> No No
Arc<T> Yes Yes
Mutex<T> Yes Yes

Concurreny models

Model Description
shared memory threads operate on regions of shared memory
worker pools many identical threads receive jobs from a shared job queue
actors many different job queues, one for each actor; actors communicate exclusively by exchanging messages
Runtime Description
tokio (multithreaded) thread pool with work-stealing scheduler: each processor maintains its own run queue; idle processor checks sibling processor run queues, and attempts to steal tasks from them
actix_rt single-threaded async runtime; futures are !Send
actix actor framework
actix-web constructs an application instance for each thread; application data must be constructed multiple times or shared between threads

Terminology

Marker trait: Used to give the compiler certain guarantees (see std::marker).

Data race: Two or more threads concurrently accessing a location of memory; one or more of them is a write; one or more of them is unsynchronized.

Thread: A native OS thread.

Green threads (or virtual threads): Threads that are scheduled by a runtime library or virtual machine (VM) instead of natively by the underlying operating system (OS).

Context switch: The process of storing the state of a process or thread, so that it can be restored and resume execution at a later point.

Synchronous I/O: blocking I/O.

Asynchronous I/O: non-blocking I/O.

Future (cf. promise): A single value produced asynchronously.

Stream: A series of values produced asynchronously.

Sink: Write data asynchronously.

Task: An asynchronous green thread.

Channel: Enables communication between threads or tasks.

Mutex (mutual exclusion): Shares data between threads or tasks.

Executor: Runs asynchronous tasks.

Generator: Used internally by the compiler. Can stop (or yield) its execution and resume (poll) afterwards from its last yield point by inspecting the previously stored state in self.

polling: Attempts to resolve the future into a final value.

io_uring: A Linux kernel system call interface for storage device asynchronous I/O operations.

References

About

Rust Concurrency Cheat Sheet

License:Apache License 2.0