Introduction
In Rust, the Sender
class is part of the standard library's std::sync::mpsc
module, which stands for "multiple producer, single consumer." The Sender
is used to send messages through a channel, which can then be received by a Receiver
. Channels provide a way for different parts of your code to communicate with each other, especially in concurrent programming.
Using Sender
To use Sender
, you need to create a channel using the std::sync::mpsc::channel
function, which returns a (Sender, Receiver)
pair. You can then use the Sender
to send messages through the channel.
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send("Hello from the spawned thread!").unwrap();
});
let received = rx.recv().unwrap();
println!("Received: {}", received);
}
// Output:
// Received: Hello from the spawned thread!
Key Methods
Below are some of the key methods exposed by the Sender
class:
send
Sends a value through the channel. This method will block if the channel's buffer is full. If the receiving end has been dropped, this method will return an Err
.
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send(42).unwrap();
});
let received = rx.recv().unwrap();
println!("Received: {}", received);
}
// Output:
// Received: 42
clone
Creates a clone of the Sender
. This is useful when you want multiple producers to send messages to the same receiver.
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
let tx1 = tx.clone();
thread::spawn(move || {
tx.send(1).unwrap();
});
thread::spawn(move || {
tx1.send(2).unwrap();
});
for _ in 0..2 {
let received = rx.recv().unwrap();
println!("Received: {}", received);
}
}
// Output (order may vary):
// Received: 1
// Received: 2
Example Usage
Example 1: Basic Usage
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send("Hello from the spawned thread!").unwrap();
});
let received = rx.recv().unwrap();
println!("Received: {}", received);
}
// Output:
// Received: Hello from the spawned thread!
Example 2: Sending Multiple Messages
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send(1).unwrap();
tx.send(2).unwrap();
tx.send(3).unwrap();
});
for _ in 0..3 {
let received = rx.recv().unwrap();
println!("Received: {}", received);
}
}
// Output:
// Received: 1
// Received: 2
// Received: 3
Example 3: Using Clone for Multiple Senders
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
let tx1 = tx.clone();
thread::spawn(move || {
tx.send(1).unwrap();
});
thread::spawn(move || {
tx1.send(2).unwrap();
});
for _ in 0..2 {
let received = rx.recv().unwrap();
println!("Received: {}", received);
}
}
// Output (order may vary):
// Received: 1
// Received: 2
Example 4: Handling Errors When the Receiver is Dropped
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
drop(rx); // Drop the receiver
match tx.send(42) {
Ok(_) => println!("Message sent successfully"),
Err(e) => println!("Failed to send message: {}", e),
}
}
// Output:
// Failed to send message: sending on a closed channel
Example 5: Using with Multiple Threads
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
let tx1 = tx.clone();
let handle1 = thread::spawn(move || {
for i in 0..5 {
tx.send(i).unwrap();
}
});
let handle2 = thread::spawn(move || {
for i in 5..10 {
tx1.send(i).unwrap();
}
});
handle1.join().unwrap();
handle2.join().unwrap();
for received in rx {
println!("Received: {}", received);
}
}
// Output:
// Received: 0
// Received: 1
// Received: 2
// Received: 3
// Received: 4
// Received: 5
// Received: 6
// Received: 7
// Received: 8
// Received: 9
Considerations
- Using
Sender::clone
, you can create multiple producers for a single receiver. Each clone can send messages independently. - Always handle the
Result
returned bysend
to manage possible errors when the receiver is dropped. - Dropping the
Sender
will close the sending side of the channel, causing the receiver to return an error once all messages have been received.
See Also
- Receiver - The receiving half of a channel used to receive messages.
- JoinHandle - A handle for managing the lifecycle of a thread.
- Mutex - A mutual exclusion primitive for protecting shared data.