Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

One technique to solve concurrency between threads involves communication. If threads are able to send each other messages, they can synchronize to, for instance, access shared resources.

The std::sync::mpsc module provides functions (see Table 1) to open communication channels between threads. In an MPSC (Multiple Producers, Single Consumer) model, only one thread listen for arriving messages, while one or more threads can emit messages.

In practice, the std::sync::mpsc module provides methods to pass ownership of an object from one thread to another.

Table 1:Functions of the mpsc module

Method

Description

channel<T>()

Creates an asynchronous channel of communication to send T objects. Returns a tuple made of a Sender<T> (transmitter) and a Receiver<T>.

sync_channel<T>(sz)

Creates a synchronous channel of communication to send T objects. Returns a tuple made of a SyncSender<T> (transmitter) and a Receiver<T>.

38.3.1Send

The channels provided by the std::sync::mpsc module are made to transmit objects of the same type from one thread to another. The only condition is that the type must implement the Send trait.

38.3.2Asynchronous channel

In an asynchronous communication, the channel has an unlimited buffer in which it stores the messages:

To open an asynchronous channel, we use the channel() function. It returns a tuple containing first a transmitter (tx), then a receiver (rx):

Couldn't automatically determine type of variable `tx`.
Please give it an explicit type.

We spawn a thread that sends a message into the channel:

We wait for a message to arrive, and then print it:

Before quiting, we make sure the spawned has terminated:

38.3.3Synchronous channel

In a synchronous communication, the channel has a size limited buffer in which it stores the messages:

To open a synchronous channel, we use the sync_channel() function. It takes as argument the buffer size (i.e.: the maximum number of messages that can be stored in it). It returns a tuple containing first a transmitter (tx), then a receiver (rx).

In the following example, we create a synchronous channel with a buffer capicity of two messages only:

We spawn a thread that sends multiple messages and prints a timestamp after each successful send:

We spawn a receiver thread that waits for messages to arrive, prints them, and pause for 20 ms after each received message:

We wait for the two threads to terminate:

We can observer that the sender thread must wait each time for a slot to be freed inside the channel, starting at the third message.

see solution

38.3.4Multiple senders

As stated in the introduction, with the std::sync::mpsc module, multiple threads can send messages, while only one can receive them. To allow multiple threads to send messages on the same channel, we just have to clone the transmitter for each new thread.

Let us create an asynchronous channel:

And clone the transmitter:

We can then spawn two sender threads using both transmitters:

And listen for arriving messages on the receiver:

We finally wait for the two threads to terminate: