Rust Multitasking API on PC
One of the obstacles when switching to a new RTOS is to get familiar with the API and programming workflow. To flatten that learning curve we can use a similar syntax a programmer is already used to. So, let us look at threads and IPC in Rust for computer systems.
Threads
use std::thread;
fn process_large_text(text: Arc<TextMap>) -> {
/*...*/
}
fn main() {
/*...*/
let handle = thread::spawn1 (move ||
process_large_text(text.clone()));2
handle.join().unwrap();3
}
Listing: Multitasking using std::thread
A new thread is created and executed immediately with the thread::spawn()
call thread::spawn()
is a capture which is similar to lambda function in other languages. This capture simply calls the process_large_text()
function and passes a reference to the text clone()
only increments the reference counter of the atomic reference counted type (Arc<>
). At join()
function will return an error. [1, pp. 457]
Inter-Process Communication (IPC)
The Rust standard library offers some support to communicate between threads. There are other solutions from the community as well, i.e. tokio
. This subsection covers mutual exclusion (Mutex
) and communication channels (channel
) from the Multi-producer single-consumer (mpsc) library.
Channel
use std::thread;
use std::sync::mpsc::channel;
let (tx, rx) = channel();1
let handle = thread::spawn(move || {
tx.send(slow_operation()).unwrap();2
});
let result = rx.recv().unwrap();3
handle.join().unwrap();
Listing: Message passing using a channel
A channel consists of one or more senders and a single receiver. At slow_operation()
is sent through the channel. The main program receives the result at
Mutex
use std::sync::Mutex;
use std::thread;
let data = Mutex::new(42i32);1
let handle = thread::spawn(move || {
let mut data_value = data.lock().unwrap();2
*data_value += 1;3
// mutex automatically unlocked when `data_value` goes out of scope
});
handle.join();
Listing: Mutual Exclusion (mutex)
In comparison to C/C++ a mutex in Rust is bound to a resource. In the listing at data_value
goes out of scope. If a thread locks a resource and then panics, the mutex is marked as poisoned. When other threads try to lock a poisoned mutex, an error is returned. [1, pp. 484]