0:00
/
0:00
Transcript

Multithreading in Rust

Creating Threads and Passing Messages

GitHub Repository: https://github.com/caveofprogramming/rust/

Creating a Thread

The following program spawns a thread and runs some code in it.

The program thus runs two threads: the main thread, and one additional thread. The sleep (which pauses the main thread here) is needed because otherwise the main thread will exit, destroying all spawned threads, before the text can be printed.

Waiting for Threads to Finish

Instead of pausing, which necessitates having to try to guess how long we need for the spawned thread to finish, or else just wait excessively long, we can wait till a thread finishes.

The unwrap here causes a panic if the thread can’t be run, because the join() function, which waits for a thread to finish, returns a Result.

Thread Interleaving

To prove that threads run concurrently, which is the point of them, we can run two threads at the same time.

In the following code, a pause is used within the loops because otherwise, one thread might finish before the other can start. There’s no guarantee about which thread runs first.

Alternatively, we can spawn two new threads and print output from those. In that case, we’d better wait for both of them to finish.

In both cases, the output ends up interleaved.

Accessing Variables at the Enclosing Scope

The following code does not compile. We are not allowed to access the variable v within the closure, because if this code were to actually compile, v could be dropped before the thread has finished with it.

The solution is to add the move keyword to the closure. This ensure local variables access within the closure are moved, so that the closure takes ownership. Drop after the thread code is then not allowed

This code compiles and works fine.

Passing Messages

When two or more threads try to modify the same variable, problems typically ensue, because the work of one thread conflicts with the other.

But this can’t easily happen in Rust, because a thread has to take ownership of a variable to be able to modify it.

There are various alternative ways of communicating between threads where needed, instead of multiple threads modifying the same variables.

One of these is to make use of messages.

The following code creates a channel that can be used to communicate between threads. mpsc stands for “multiple producer, single consumer”.

That is, multiple threads can send data down the channel, and one thread can consume it.

tx is the “transmitter” and rx the “receiver”.

The send method is used to send data, and the recv (short for receive) method is used to receive it.

Multiple Senders

In this code, minimally adapted from the Rust documentation, multiple receivers send to a channel.

Note:

  • The transmitter is cloned. Otherwise it would be unavailable after moving into the first sender thread code.

  • The senders send text with one-second delays. The receiver actually blocks until data is available, so the receiver gradually spits out the transmitted strings.

  • The receiver thread is using the receiver as an iterator, rather than calling recv().

The order of the output may vary.

Discussion about this video

User's avatar