mpsc
import std::sync::mpsc; · source
Types
Sender<T>
type struct Sender<T> {
inner: ChannelInner<T>*;
send(&this, value: T) -> Result<(), SendError<T>>;
clone(&this) -> Sender<T>;
close(mut this) -> void;
}
send moves a value into the queue. clone() mints another producer; close() consumes the sender and is equivalent to dropping it early.
Properties
| Property | Type |
|---|---|
inner | ChannelInner<T>* |
Methods
send(&this, value: T) -> Result<(), SendError<T>>;
send(&this, value: T) -> Result<(), SendError<T>>;Enqueue value. Returns Err(SendError{value}) if the receiver has already been dropped (the value is handed back unconsumed).
clone(&this) -> Sender<T>;
clone(&this) -> Sender<T>;Create another sender on the same channel (multi-producer).
close(mut this) -> void;
close(mut this) -> void;Explicitly drop this sender now (rather than at scope end). Useful after moving a sender into a thread body, where the value must be released before the body returns.
Receiver<T>
type struct Receiver<T> {
inner: ChannelInner<T>*;
sender(&this) -> Sender<T>;
recv(&this) -> Result<T, RecvError>;
try_recv(&this) -> Result<T, TryRecvError>;
}
recv() blocks; try_recv() returns Err(Empty) immediately when nothing is queued. sender() mints producers from the receiver, which is why channel returns only the receiver.
Properties
| Property | Type |
|---|---|
inner | ChannelInner<T>* |
Methods
sender(&this) -> Sender<T>;
sender(&this) -> Sender<T>;Create a new Sender<T> feeding this channel. Call once per producer (each returned sender is independently owned and may be moved into its own thread); clone an existing sender as an alternative. The channel stays open for recv as long as any sender is alive.
recv(&this) -> Result<T, RecvError>;
recv(&this) -> Result<T, RecvError>;Block until a value is available and return it, or return Err(Disconnected) once every sender has dropped and the queue is drained.
try_recv(&this) -> Result<T, TryRecvError>;
try_recv(&this) -> Result<T, TryRecvError>;Non-blocking receive. Returns Err(Empty) if no value is ready but senders remain, Err(Disconnected) if the channel is drained and all senders have dropped.
The errors
type struct SendError<T> {
value: T;
}
type enum RecvError {
Disconnected;
}
type enum TryRecvError {
Empty;
Disconnected;
}
SendError
Properties
| Property | Type |
|---|---|
value | T |
RecvError
Variants
| Variant |
|---|
Disconnected |
TryRecvError
Variants
| Variant |
|---|
Empty |
Disconnected |
Disconnection
When every Sender has been dropped, a blocked recv() returns Err(RecvError::Disconnected) and try_recv() returns Err(TryRecvError::Disconnected).
When the Receiver is dropped, send() returns Err(SendError) handing the value back, rather than queueing into a channel nobody will drain.
Underneath, a heap inner holds a mutex and condition variable guarding a raw singly-linked node queue, plus a live-sender count and a total-handle refcount; the inner is reclaimed when the last handle of either kind drops. Values move out of dequeued nodes through raw pointers, so the move-checker sees each as a clean transfer — no aliasing, no double free.
Trait implementations
Sender
implement<T> trait Drop for struct Sender<T>
Receiver
implement<T> trait Drop for struct Receiver<T>
Receiver::drop drains and drops whatever is still queued, which is why it carries the T: Drop bound.
Free Functions
function channel<T>() -> Receiver<T>;
function channel<T>() -> Receiver<T>;Create an unbounded channel and return its Receiver<T> - the channel's owning end. Mint one or more producers with rx.sender() (each is independently owned and movable into its own thread):
Each Sender<T> is independently owned and movable into its own thread, and cloneable for further fan-out. Values of any type — including owned data like String — move through an unbounded FIFO queue.
import std::sync::mpsc;
import std::thread;
mut rx: mpsc::Receiver<i32> = mpsc::channel::<i32>();
const tx: mpsc::Sender<i32> = rx.sender();
const h = thread::spawn::<mpsc::Sender<i32>, i32>(tx, (s: mpsc::Sender<i32>) -> i32 {
mut snd: mpsc::Sender<i32> = s;
snd.send(42);
snd.close();
return 0;
});
match (rx.recv()) {
Result::Ok(v) => { use(v); }
Result::Err(_) => { }
}
h.join();
type struct Name { ... }
type enum Name { ... }
type trait Name { ... }
type union Name { ... }Begins a type declaration; the keyword that follows says which kind. On its own, type Name = Existing; declares an alias.
type struct Name {
field: Type;
method(&this) -> Ret { ... }
}A value type with named fields and optional methods. Structs live on the stack and are passed by value. Fields are public by default and may carry = default values; methods take their receiver as &this, mut &this, or this.
type struct Sender<T> {
inner: ChannelInner<T>*;
}The sending half of a channel. Cloneable for multiple producers.
type parameter TSender.inner: ChannelInner<T>*type struct ChannelInner<T> {
mutex: [u8;
40];
cond: [u8;
48];
head: ChanNode<T>*;
tail: ChanNode<T>*;
senders: i64;
refs: i64;
rx_open: boolean;
}Shared channel state. Heap-pinned: the pthread buffers must not move after init while threads block on them.
std::sync::mpsctype parameter TSender::send(&this, value: T) -> Result<(), SendError<T>>Enqueue value. Returns Err(SendError{value}) if the receiver has already been dropped (the value is handed back unconsumed).
&this
mut &this
thisThe receiver of a method. Its first parameter declares how the method takes it: &this borrows read-only, mut &this borrows exclusively, and this / mut this move the value in and consume it. In the body, this.field reaches the members.
(parameter) value: Tprimitive ()The unit type: a value that carries no information, and the empty tuple. Distinct from void, which is the absence of a value - Result<(), E> succeeds with nothing to return. 0 bytes.
type struct SendError<T> {
value: T;
}Error returned by Sender::send when the receiver has been dropped. Carries the value back so the caller does not lose it.
Sender::clone(&this) -> Sender<T>Create another sender on the same channel (multi-producer).
type struct Sender<T> {
inner: ChannelInner<T>*;
}The sending half of a channel. Cloneable for multiple producers.
std::sync::mpscSender::close(mut this) -> voidExplicitly drop this sender now (rather than at scope end). Useful after moving a sender into a thread body, where the value must be released before the body returns.
mut thisA by-value receiver the body may also reassign. The receiver is moved into the method and consumed; the caller's value may not be used afterwards.
language referencetype struct Receiver<T> {
inner: ChannelInner<T>*;
}The receiving half of a channel, and the channel's owner. Not cloneable (single consumer); mint producers with sender().
Receiver.inner: ChannelInner<T>*type parameter TReceiver::sender(&this) -> Sender<T>Create a new Sender<T> feeding this channel. Call once per producer (each returned sender is independently owned and may be moved into its own thread); clone an existing sender as an alternative. The channel stays open for recv as long as any sender is alive.
Receiver::recv(&this) -> Result<T, RecvError>Block until a value is available and return it, or return Err(Disconnected) once every sender has dropped and the queue is drained.
Receiver::try_recv(&this) -> Result<T, TryRecvError>Non-blocking receive. Returns Err(Empty) if no value is ready but senders remain, Err(Disconnected) if the channel is drained and all senders have dropped.
type enum TryRecvError {
Empty;
Disconnected;
}Error returned by the non-blocking Receiver::try_recv.
type struct SendError<T> {
value: T;
}Error returned by Sender::send when the receiver has been dropped. Carries the value back so the caller does not lose it.
SendError.value: Ttype parameter Ttype enum Name {
Unit,
Payload(T),
Named { x: i32 },
}An algebraic data type. Variants may be bare or carry a tuple or struct payload, and a match on an enum must cover every variant. Name::Variant names a variant; methods are added with implement enum Name { ... }.
type enum RecvError {
Disconnected;
}Error returned by a blocking Receiver::recv.
RecvError::Disconnectedtype enum TryRecvError {
Empty;
Disconnected;
}Error returned by the non-blocking Receiver::try_recv.
TryRecvError::EmptyTryRecvError::Disconnectedimport a::b;
import a::b::{ X, Y };
import a::b as c;
import a::b::*;Brings a module, or selected items from it, into scope. One path per declaration: use the brace form for several items, as to alias, and * for everything public (prefer the brace form; wildcards invite name collisions).
mut name: Type = value;A mutable binding, reassignable after declaration - mutability is opt-in, const is the default. At module level it declares mutable global state. Before & it marks an exclusive reference or receiver instead.
mut rx: mpsc::Receiver<i32>type struct Receiver<T> {
inner: ChannelInner<T>*;
}The receiving half of a channel, and the channel's owner. Not cloneable (single consumer); mint producers with sender().
function channel<T>() -> Receiver<T>Create an unbounded channel and return its Receiver<T> - the channel's owning end. Mint one or more producers with rx.sender() (each is independently owned and movable into its own thread):
const NAME: Type = value;At module level, a true compile-time constant, conventionally SCREAMING_SNAKE_CASE. (mut at module level declares mutable global state instead.)
const tx: mpsc::Sender<i32>mut rx: mpsc::Receiver<i32>Receiver::sender(&this) -> Sender<T>Create a new Sender<T> feeding this channel. Call once per producer (each returned sender is independently owned and may be moved into its own thread); clone an existing sender as an alternative. The channel stays open for recv as long as any sender is alive.
const h: JoinHandle<i32>function spawn<C, T>(ctx: C, body: (C) -> T) -> JoinHandle<T>
where C: Send, T: SendSpawn a thread that runs body(ctx) and returns a handle to its T result. ctx is moved into the new thread. body must be a function pointer or non-capturing lambda. Panics on allocation or pthread_create failure; use try_spawn for a fallible spawn.
const tx: mpsc::Sender<i32>(parameter) s: mpsc::Sender<i32>mut snd: mpsc::Sender<i32>(parameter) s: mpsc::Sender<i32>mut snd: mpsc::Sender<i32>Sender::send(&this, value: T) -> Result<(), SendError<T>>Enqueue value. Returns Err(SendError{value}) if the receiver has already been dropped (the value is handed back unconsumed).
Sender::close(mut this) -> voidExplicitly drop this sender now (rather than at scope end). Useful after moving a sender into a thread body, where the value must be released before the body returns.
std::sync::mpscreturn value;Leaves the current function with the given value. A function whose return type is not void must return one; a bare return; is for void. In an async function it completes the future with the value.
match (subject) {
Pattern(x) => { ... }
_ => { ... }
}The primary discriminator: branches on enum variants, integers, ranges, and destructuring patterns, and the compiler rejects a match that misses a case. There is no fallthrough. As an expression it evaluates to the chosen arm's value, so every arm must produce the same type.
Receiver::recv(&this) -> Result<T, RecvError>Block until a value is available and return it, or return Err(Disconnected) once every sender has dropped and the queue is drained.
Result::Ok(T)v: i32pattern => { body }Separates a match arm's pattern from its body. Arms do not fall through.
v: i32Result::Err(E)_const h: JoinHandle<i32>JoinHandle::join(mut this) -> TBlock until the thread finishes and return its result. Consumes the handle; the control block is freed here.
std::threadSender::clone(&this) -> Sender<T>Create another sender on the same channel (multi-producer).
std::sync::mpscSender.inner: ChannelInner<T>*ChanNode.value: TSendError.value: TReceiver::try_recv(&this) -> Result<T, TryRecvError>Non-blocking receive. Returns Err(Empty) if no value is ready but senders remain, Err(Disconnected) if the channel is drained and all senders have dropped.
TryRecvError::EmptyRecvError::DisconnectedTryRecvError::Disconnectedimplement struct Name { ... }
implement trait Trait for Type { ... }
implement u64 { ... }Adds methods to a type outside its declaration. implement struct T (or enum, or a bare primitive) opens an inherent block; implement trait Tr for T supplies a trait's methods for one type. Resolution is at compile time - no dynamic dispatch.
type trait Name : Base {
method(&this, other: &This) -> Ret;
}Names a set of methods a type may implement. Inside the body This is the implementing type; methods may carry default bodies, and a trait may require a base trait (type trait Ord : Eq). Generic code asks for a trait with where T: Name.
implement trait Trait for Type { ... }Names the type a trait implementation is for. The block that follows supplies the bodies the trait requires.
language referencefunction name<T>(param: Type) -> Ret { ... }Declares a function. Parameters are written name: Type and are never inferred; the return type follows -> and defaults to void. Declaration order does not matter: every signature is collected before any body is checked, so functions may call each other freely and recurse.
function channel<T>() -> Receiver<T>Create an unbounded channel and return its Receiver<T> - the channel's owning end. Mint one or more producers with rx.sender() (each is independently owned and movable into its own thread):
type struct String<A = GlobalAlloc> {
buffer: RawBuffer<u8, A>;
length: u64;
}String: owned, heap-allocated, length-typed UTF-8.
std::collections::string