This repository has been archived on 2022-04-04. You can view files and clone it, but cannot push or open issues or pull requests.

298 lines
36 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Multi-producer multi-consumer channels for message passing."><meta name="keywords" content="rust, rustlang, rust-lang, crossbeam_channel"><title>crossbeam_channel - Rust</title><link rel="preload" as="font" type="font/woff2" crossorigin href="../SourceSerif4-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../FiraSans-Regular.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../FiraSans-Medium.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../SourceCodePro-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../SourceSerif4-Bold.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../SourceCodePro-Semibold.ttf.woff2"><link rel="stylesheet" type="text/css" href="../normalize.css"><link rel="stylesheet" type="text/css" href="../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" type="text/css" href="../ayu.css" disabled><link rel="stylesheet" type="text/css" href="../dark.css" disabled><link rel="stylesheet" type="text/css" href="../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../storage.js"></script><script src="../crates.js"></script><script defer src="../main.js"></script>
<noscript><link rel="stylesheet" href="../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../favicon.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="sidebar-menu" role="button">&#9776;</div><a class="sidebar-logo" href="../crossbeam_channel/index.html"><div class="logo-container"><img class="rust-logo" src="../rust-logo.png" alt="logo"></div>
</a><h2 class="location">Crate crossbeam_channel</h2><div class="block version"><div class="narrow-helper"></div><p>Version 0.5.4</p></div><div class="sidebar-elems"><a id="all-types" href="all.html"><p>See all crossbeam_channel's items</p></a><div class="block items"><ul><li><a href="#macros">Macros</a></li><li><a href="#structs">Structs</a></li><li><a href="#enums">Enums</a></li><li><a href="#functions">Functions</a></li></ul></div><div id="sidebar-vars" data-name="crossbeam_channel" data-ty="mod" data-relpath=""></div><script defer src="sidebar-items.js"></script></div></nav><main><div class="width-limiter"><div class="sub-container"><a class="sub-logo-container" href="../crossbeam_channel/index.html"><img class="rust-logo" src="../rust-logo.png" alt="logo"></a><nav class="sub"><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu" title="themes"><img width="18" height="18" alt="Pick another theme!" src="../brush.svg"></button><div id="theme-choices" role="menu"></div></div><form class="search-form"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"></div><button type="button" id="help-button" title="help">?</button><a id="settings-menu" href="../settings.html" title="settings"><img width="18" height="18" alt="Change settings" src="../wheel.svg"></a></div></form></nav></div><section id="main-content" class="content"><h1 class="fqn"><span class="in-band">Crate <a class="mod" href="#">crossbeam_channel</a><button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"><img src="../clipboard.svg" width="19" height="18" alt="Copy item path"></button></span><span class="out-of-band"><span id="render-detail"><a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class="inner">&#x2212;</span>]</a></span><a class="srclink" href="../src/crossbeam_channel/lib.rs.html#1-371" title="goto source code">[src]</a></span></h1><details class="rustdoc-toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Multi-producer multi-consumer channels for message passing.</p>
<p>This crate is an alternative to <a href="https://doc.rust-lang.org/1.59.0/std/sync/mpsc/index.html" title="std::sync::mpsc"><code>std::sync::mpsc</code></a> with more features and better performance.</p>
<h2 id="hello-world" class="section-header"><a href="#hello-world">Hello, world!</a></h2>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">crossbeam_channel::unbounded</span>;
<span class="comment">// Create a channel of unbounded capacity.</span>
<span class="kw">let</span> (<span class="ident">s</span>, <span class="ident">r</span>) <span class="op">=</span> <span class="ident">unbounded</span>();
<span class="comment">// Send a message into the channel.</span>
<span class="ident">s</span>.<span class="ident">send</span>(<span class="string">&quot;Hello, world!&quot;</span>).<span class="ident">unwrap</span>();
<span class="comment">// Receive the message from the channel.</span>
<span class="macro">assert_eq!</span>(<span class="ident">r</span>.<span class="ident">recv</span>(), <span class="prelude-val">Ok</span>(<span class="string">&quot;Hello, world!&quot;</span>));</code></pre></div>
<h2 id="channel-types" class="section-header"><a href="#channel-types">Channel types</a></h2>
<p>Channels can be created using two functions:</p>
<ul>
<li>
<p><a href="fn.bounded.html" title="bounded"><code>bounded</code></a> creates a channel of bounded capacity, i.e. there is a limit to how many messages
it can hold at a time.</p>
</li>
<li>
<p><a href="fn.unbounded.html" title="unbounded"><code>unbounded</code></a> creates a channel of unbounded capacity, i.e. it can hold any number of
messages at a time.</p>
</li>
</ul>
<p>Both functions return a <a href="struct.Sender.html" title="Sender"><code>Sender</code></a> and a <a href="struct.Receiver.html" title="Receiver"><code>Receiver</code></a>, which represent the two opposite sides
of a channel.</p>
<p>Creating a bounded channel:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">crossbeam_channel::bounded</span>;
<span class="comment">// Create a channel that can hold at most 5 messages at a time.</span>
<span class="kw">let</span> (<span class="ident">s</span>, <span class="ident">r</span>) <span class="op">=</span> <span class="ident">bounded</span>(<span class="number">5</span>);
<span class="comment">// Can send only 5 messages without blocking.</span>
<span class="kw">for</span> <span class="ident">i</span> <span class="kw">in</span> <span class="number">0</span>..<span class="number">5</span> {
<span class="ident">s</span>.<span class="ident">send</span>(<span class="ident">i</span>).<span class="ident">unwrap</span>();
}
<span class="comment">// Another call to `send` would block because the channel is full.</span>
<span class="comment">// s.send(5).unwrap();</span></code></pre></div>
<p>Creating an unbounded channel:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">crossbeam_channel::unbounded</span>;
<span class="comment">// Create an unbounded channel.</span>
<span class="kw">let</span> (<span class="ident">s</span>, <span class="ident">r</span>) <span class="op">=</span> <span class="ident">unbounded</span>();
<span class="comment">// Can send any number of messages into the channel without blocking.</span>
<span class="kw">for</span> <span class="ident">i</span> <span class="kw">in</span> <span class="number">0</span>..<span class="number">1000</span> {
<span class="ident">s</span>.<span class="ident">send</span>(<span class="ident">i</span>).<span class="ident">unwrap</span>();
}</code></pre></div>
<p>A special case is zero-capacity channel, which cannot hold any messages. Instead, send and
receive operations must appear at the same time in order to pair up and pass the message over:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">std::thread</span>;
<span class="kw">use</span> <span class="ident">crossbeam_channel::bounded</span>;
<span class="comment">// Create a zero-capacity channel.</span>
<span class="kw">let</span> (<span class="ident">s</span>, <span class="ident">r</span>) <span class="op">=</span> <span class="ident">bounded</span>(<span class="number">0</span>);
<span class="comment">// Sending blocks until a receive operation appears on the other side.</span>
<span class="ident">thread::spawn</span>(<span class="kw">move</span> <span class="op">|</span><span class="op">|</span> <span class="ident">s</span>.<span class="ident">send</span>(<span class="string">&quot;Hi!&quot;</span>).<span class="ident">unwrap</span>());
<span class="comment">// Receiving blocks until a send operation appears on the other side.</span>
<span class="macro">assert_eq!</span>(<span class="ident">r</span>.<span class="ident">recv</span>(), <span class="prelude-val">Ok</span>(<span class="string">&quot;Hi!&quot;</span>));</code></pre></div>
<h2 id="sharing-channels" class="section-header"><a href="#sharing-channels">Sharing channels</a></h2>
<p>Senders and receivers can be cloned and sent to other threads:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">std::thread</span>;
<span class="kw">use</span> <span class="ident">crossbeam_channel::bounded</span>;
<span class="kw">let</span> (<span class="ident">s1</span>, <span class="ident">r1</span>) <span class="op">=</span> <span class="ident">bounded</span>(<span class="number">0</span>);
<span class="kw">let</span> (<span class="ident">s2</span>, <span class="ident">r2</span>) <span class="op">=</span> (<span class="ident">s1</span>.<span class="ident">clone</span>(), <span class="ident">r1</span>.<span class="ident">clone</span>());
<span class="comment">// Spawn a thread that receives a message and then sends one.</span>
<span class="ident">thread::spawn</span>(<span class="kw">move</span> <span class="op">|</span><span class="op">|</span> {
<span class="ident">r2</span>.<span class="ident">recv</span>().<span class="ident">unwrap</span>();
<span class="ident">s2</span>.<span class="ident">send</span>(<span class="number">2</span>).<span class="ident">unwrap</span>();
});
<span class="comment">// Send a message and then receive one.</span>
<span class="ident">s1</span>.<span class="ident">send</span>(<span class="number">1</span>).<span class="ident">unwrap</span>();
<span class="ident">r1</span>.<span class="ident">recv</span>().<span class="ident">unwrap</span>();</code></pre></div>
<p>Note that cloning only creates a new handle to the same sending or receiving side. It does not
create a separate stream of messages in any way:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">crossbeam_channel::unbounded</span>;
<span class="kw">let</span> (<span class="ident">s1</span>, <span class="ident">r1</span>) <span class="op">=</span> <span class="ident">unbounded</span>();
<span class="kw">let</span> (<span class="ident">s2</span>, <span class="ident">r2</span>) <span class="op">=</span> (<span class="ident">s1</span>.<span class="ident">clone</span>(), <span class="ident">r1</span>.<span class="ident">clone</span>());
<span class="kw">let</span> (<span class="ident">s3</span>, <span class="ident">r3</span>) <span class="op">=</span> (<span class="ident">s2</span>.<span class="ident">clone</span>(), <span class="ident">r2</span>.<span class="ident">clone</span>());
<span class="ident">s1</span>.<span class="ident">send</span>(<span class="number">10</span>).<span class="ident">unwrap</span>();
<span class="ident">s2</span>.<span class="ident">send</span>(<span class="number">20</span>).<span class="ident">unwrap</span>();
<span class="ident">s3</span>.<span class="ident">send</span>(<span class="number">30</span>).<span class="ident">unwrap</span>();
<span class="macro">assert_eq!</span>(<span class="ident">r3</span>.<span class="ident">recv</span>(), <span class="prelude-val">Ok</span>(<span class="number">10</span>));
<span class="macro">assert_eq!</span>(<span class="ident">r1</span>.<span class="ident">recv</span>(), <span class="prelude-val">Ok</span>(<span class="number">20</span>));
<span class="macro">assert_eq!</span>(<span class="ident">r2</span>.<span class="ident">recv</span>(), <span class="prelude-val">Ok</span>(<span class="number">30</span>));</code></pre></div>
<p>Its also possible to share senders and receivers by reference:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">crossbeam_channel::bounded</span>;
<span class="kw">use</span> <span class="ident">crossbeam_utils::thread::scope</span>;
<span class="kw">let</span> (<span class="ident">s</span>, <span class="ident">r</span>) <span class="op">=</span> <span class="ident">bounded</span>(<span class="number">0</span>);
<span class="ident">scope</span>(<span class="op">|</span><span class="ident">scope</span><span class="op">|</span> {
<span class="comment">// Spawn a thread that receives a message and then sends one.</span>
<span class="ident">scope</span>.<span class="ident">spawn</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span> {
<span class="ident">r</span>.<span class="ident">recv</span>().<span class="ident">unwrap</span>();
<span class="ident">s</span>.<span class="ident">send</span>(<span class="number">2</span>).<span class="ident">unwrap</span>();
});
<span class="comment">// Send a message and then receive one.</span>
<span class="ident">s</span>.<span class="ident">send</span>(<span class="number">1</span>).<span class="ident">unwrap</span>();
<span class="ident">r</span>.<span class="ident">recv</span>().<span class="ident">unwrap</span>();
}).<span class="ident">unwrap</span>();</code></pre></div>
<h2 id="disconnection" class="section-header"><a href="#disconnection">Disconnection</a></h2>
<p>When all senders or all receivers associated with a channel get dropped, the channel becomes
disconnected. No more messages can be sent, but any remaining messages can still be received.
Send and receive operations on a disconnected channel never block.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">crossbeam_channel</span>::{<span class="ident">unbounded</span>, <span class="ident">RecvError</span>};
<span class="kw">let</span> (<span class="ident">s</span>, <span class="ident">r</span>) <span class="op">=</span> <span class="ident">unbounded</span>();
<span class="ident">s</span>.<span class="ident">send</span>(<span class="number">1</span>).<span class="ident">unwrap</span>();
<span class="ident">s</span>.<span class="ident">send</span>(<span class="number">2</span>).<span class="ident">unwrap</span>();
<span class="ident">s</span>.<span class="ident">send</span>(<span class="number">3</span>).<span class="ident">unwrap</span>();
<span class="comment">// The only sender is dropped, disconnecting the channel.</span>
<span class="ident">drop</span>(<span class="ident">s</span>);
<span class="comment">// The remaining messages can be received.</span>
<span class="macro">assert_eq!</span>(<span class="ident">r</span>.<span class="ident">recv</span>(), <span class="prelude-val">Ok</span>(<span class="number">1</span>));
<span class="macro">assert_eq!</span>(<span class="ident">r</span>.<span class="ident">recv</span>(), <span class="prelude-val">Ok</span>(<span class="number">2</span>));
<span class="macro">assert_eq!</span>(<span class="ident">r</span>.<span class="ident">recv</span>(), <span class="prelude-val">Ok</span>(<span class="number">3</span>));
<span class="comment">// There are no more messages in the channel.</span>
<span class="macro">assert!</span>(<span class="ident">r</span>.<span class="ident">is_empty</span>());
<span class="comment">// Note that calling `r.recv()` does not block.</span>
<span class="comment">// Instead, `Err(RecvError)` is returned immediately.</span>
<span class="macro">assert_eq!</span>(<span class="ident">r</span>.<span class="ident">recv</span>(), <span class="prelude-val">Err</span>(<span class="ident">RecvError</span>));</code></pre></div>
<h2 id="blocking-operations" class="section-header"><a href="#blocking-operations">Blocking operations</a></h2>
<p>Send and receive operations come in three flavors:</p>
<ul>
<li>Non-blocking (returns immediately with success or failure).</li>
<li>Blocking (waits until the operation succeeds or the channel becomes disconnected).</li>
<li>Blocking with a timeout (blocks only for a certain duration of time).</li>
</ul>
<p>A simple example showing the difference between non-blocking and blocking operations:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">crossbeam_channel</span>::{<span class="ident">bounded</span>, <span class="ident">RecvError</span>, <span class="ident">TryRecvError</span>};
<span class="kw">let</span> (<span class="ident">s</span>, <span class="ident">r</span>) <span class="op">=</span> <span class="ident">bounded</span>(<span class="number">1</span>);
<span class="comment">// Send a message into the channel.</span>
<span class="ident">s</span>.<span class="ident">send</span>(<span class="string">&quot;foo&quot;</span>).<span class="ident">unwrap</span>();
<span class="comment">// This call would block because the channel is full.</span>
<span class="comment">// s.send(&quot;bar&quot;).unwrap();</span>
<span class="comment">// Receive the message.</span>
<span class="macro">assert_eq!</span>(<span class="ident">r</span>.<span class="ident">recv</span>(), <span class="prelude-val">Ok</span>(<span class="string">&quot;foo&quot;</span>));
<span class="comment">// This call would block because the channel is empty.</span>
<span class="comment">// r.recv();</span>
<span class="comment">// Try receiving a message without blocking.</span>
<span class="macro">assert_eq!</span>(<span class="ident">r</span>.<span class="ident">try_recv</span>(), <span class="prelude-val">Err</span>(<span class="ident">TryRecvError::Empty</span>));
<span class="comment">// Disconnect the channel.</span>
<span class="ident">drop</span>(<span class="ident">s</span>);
<span class="comment">// This call doesn&#39;t block because the channel is now disconnected.</span>
<span class="macro">assert_eq!</span>(<span class="ident">r</span>.<span class="ident">recv</span>(), <span class="prelude-val">Err</span>(<span class="ident">RecvError</span>));</code></pre></div>
<h2 id="iteration" class="section-header"><a href="#iteration">Iteration</a></h2>
<p>Receivers can be used as iterators. For example, method <a href="struct.Receiver.html#method.iter"><code>iter</code></a> creates an iterator that
receives messages until the channel becomes empty and disconnected. Note that iteration may
block waiting for next message to arrive.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">std::thread</span>;
<span class="kw">use</span> <span class="ident">crossbeam_channel::unbounded</span>;
<span class="kw">let</span> (<span class="ident">s</span>, <span class="ident">r</span>) <span class="op">=</span> <span class="ident">unbounded</span>();
<span class="ident">thread::spawn</span>(<span class="kw">move</span> <span class="op">|</span><span class="op">|</span> {
<span class="ident">s</span>.<span class="ident">send</span>(<span class="number">1</span>).<span class="ident">unwrap</span>();
<span class="ident">s</span>.<span class="ident">send</span>(<span class="number">2</span>).<span class="ident">unwrap</span>();
<span class="ident">s</span>.<span class="ident">send</span>(<span class="number">3</span>).<span class="ident">unwrap</span>();
<span class="ident">drop</span>(<span class="ident">s</span>); <span class="comment">// Disconnect the channel.</span>
});
<span class="comment">// Collect all messages from the channel.</span>
<span class="comment">// Note that the call to `collect` blocks until the sender is dropped.</span>
<span class="kw">let</span> <span class="ident">v</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">r</span>.<span class="ident">iter</span>().<span class="ident">collect</span>();
<span class="macro">assert_eq!</span>(<span class="ident">v</span>, [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]);</code></pre></div>
<p>A non-blocking iterator can be created using <a href="struct.Receiver.html#method.try_iter"><code>try_iter</code></a>, which receives all available
messages without blocking:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">crossbeam_channel::unbounded</span>;
<span class="kw">let</span> (<span class="ident">s</span>, <span class="ident">r</span>) <span class="op">=</span> <span class="ident">unbounded</span>();
<span class="ident">s</span>.<span class="ident">send</span>(<span class="number">1</span>).<span class="ident">unwrap</span>();
<span class="ident">s</span>.<span class="ident">send</span>(<span class="number">2</span>).<span class="ident">unwrap</span>();
<span class="ident">s</span>.<span class="ident">send</span>(<span class="number">3</span>).<span class="ident">unwrap</span>();
<span class="comment">// No need to drop the sender.</span>
<span class="comment">// Receive all messages currently in the channel.</span>
<span class="kw">let</span> <span class="ident">v</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">r</span>.<span class="ident">try_iter</span>().<span class="ident">collect</span>();
<span class="macro">assert_eq!</span>(<span class="ident">v</span>, [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]);</code></pre></div>
<h2 id="selection" class="section-header"><a href="#selection">Selection</a></h2>
<p>The <a href="macro.select.html" title="select!"><code>select!</code></a> macro allows you to define a set of channel operations, wait until any one of
them becomes ready, and finally execute it. If multiple operations are ready at the same time,
a random one among them is selected.</p>
<p>It is also possible to define a <code>default</code> case that gets executed if none of the operations are
ready, either right away or for a certain duration of time.</p>
<p>An operation is considered to be ready if it doesnt have to block. Note that it is ready even
when it will simply return an error because the channel is disconnected.</p>
<p>An example of receiving a message from two channels:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">std::thread</span>;
<span class="kw">use</span> <span class="ident">std::time::Duration</span>;
<span class="kw">use</span> <span class="ident">crossbeam_channel</span>::{<span class="ident">select</span>, <span class="ident">unbounded</span>};
<span class="kw">let</span> (<span class="ident">s1</span>, <span class="ident">r1</span>) <span class="op">=</span> <span class="ident">unbounded</span>();
<span class="kw">let</span> (<span class="ident">s2</span>, <span class="ident">r2</span>) <span class="op">=</span> <span class="ident">unbounded</span>();
<span class="ident">thread::spawn</span>(<span class="kw">move</span> <span class="op">|</span><span class="op">|</span> <span class="ident">s1</span>.<span class="ident">send</span>(<span class="number">10</span>).<span class="ident">unwrap</span>());
<span class="ident">thread::spawn</span>(<span class="kw">move</span> <span class="op">|</span><span class="op">|</span> <span class="ident">s2</span>.<span class="ident">send</span>(<span class="number">20</span>).<span class="ident">unwrap</span>());
<span class="comment">// At most one of these two receive operations will be executed.</span>
<span class="macro">select!</span> {
<span class="ident">recv</span>(<span class="ident">r1</span>) -&gt; <span class="ident">msg</span> =&gt; <span class="macro">assert_eq!</span>(<span class="ident">msg</span>, <span class="prelude-val">Ok</span>(<span class="number">10</span>)),
<span class="ident">recv</span>(<span class="ident">r2</span>) -&gt; <span class="ident">msg</span> =&gt; <span class="macro">assert_eq!</span>(<span class="ident">msg</span>, <span class="prelude-val">Ok</span>(<span class="number">20</span>)),
<span class="ident">default</span>(<span class="ident">Duration::from_secs</span>(<span class="number">1</span>)) =&gt; <span class="macro">println!</span>(<span class="string">&quot;timed out&quot;</span>),
}</code></pre></div>
<p>If you need to select over a dynamically created list of channel operations, use <a href="struct.Select.html" title="Select"><code>Select</code></a>
instead. The <a href="macro.select.html" title="select!"><code>select!</code></a> macro is just a convenience wrapper around <a href="struct.Select.html" title="Select"><code>Select</code></a>.</p>
<h2 id="extra-channels" class="section-header"><a href="#extra-channels">Extra channels</a></h2>
<p>Three functions can create special kinds of channels, all of which return just a <a href="struct.Receiver.html" title="Receiver"><code>Receiver</code></a>
handle:</p>
<ul>
<li><a href="fn.after.html" title="after"><code>after</code></a> creates a channel that delivers a single message after a certain duration of time.</li>
<li><a href="fn.tick.html" title="tick"><code>tick</code></a> creates a channel that delivers messages periodically.</li>
<li><a href="fn.never.html"><code>never</code></a> creates a channel that never delivers messages.</li>
</ul>
<p>These channels are very efficient because messages get lazily generated on receive operations.</p>
<p>An example that prints elapsed time every 50 milliseconds for the duration of 1 second:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use</span> <span class="ident">std::time</span>::{<span class="ident">Duration</span>, <span class="ident">Instant</span>};
<span class="kw">use</span> <span class="ident">crossbeam_channel</span>::{<span class="ident">after</span>, <span class="ident">select</span>, <span class="ident">tick</span>};
<span class="kw">let</span> <span class="ident">start</span> <span class="op">=</span> <span class="ident">Instant::now</span>();
<span class="kw">let</span> <span class="ident">ticker</span> <span class="op">=</span> <span class="ident">tick</span>(<span class="ident">Duration::from_millis</span>(<span class="number">50</span>));
<span class="kw">let</span> <span class="ident">timeout</span> <span class="op">=</span> <span class="ident">after</span>(<span class="ident">Duration::from_secs</span>(<span class="number">1</span>));
<span class="kw">loop</span> {
<span class="macro">select!</span> {
<span class="ident">recv</span>(<span class="ident">ticker</span>) -&gt; <span class="kw">_</span> =&gt; <span class="macro">println!</span>(<span class="string">&quot;elapsed: {:?}&quot;</span>, <span class="ident">start</span>.<span class="ident">elapsed</span>()),
<span class="ident">recv</span>(<span class="ident">timeout</span>) -&gt; <span class="kw">_</span> =&gt; <span class="kw">break</span>,
}
}</code></pre></div>
</div></details><h2 id="macros" class="small-section-header"><a href="#macros">Macros</a></h2>
<div class="item-table"><div class="item-row"><div class="item-left module-item"><a class="macro" href="macro.select.html" title="crossbeam_channel::select macro">select</a></div><div class="item-right docblock-short"><p>Selects from a set of channel operations.</p>
</div></div></div><h2 id="structs" class="small-section-header"><a href="#structs">Structs</a></h2>
<div class="item-table"><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.IntoIter.html" title="crossbeam_channel::IntoIter struct">IntoIter</a></div><div class="item-right docblock-short"><p>A blocking iterator over messages in a channel.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.Iter.html" title="crossbeam_channel::Iter struct">Iter</a></div><div class="item-right docblock-short"><p>A blocking iterator over messages in a channel.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.ReadyTimeoutError.html" title="crossbeam_channel::ReadyTimeoutError struct">ReadyTimeoutError</a></div><div class="item-right docblock-short"><p>An error returned from the <a href="struct.Select.html#method.ready_timeout"><code>ready_timeout</code></a> method.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.Receiver.html" title="crossbeam_channel::Receiver struct">Receiver</a></div><div class="item-right docblock-short"><p>The receiving side of a channel.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.RecvError.html" title="crossbeam_channel::RecvError struct">RecvError</a></div><div class="item-right docblock-short"><p>An error returned from the <a href="struct.Receiver.html#method.recv"><code>recv</code></a> method.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.Select.html" title="crossbeam_channel::Select struct">Select</a></div><div class="item-right docblock-short"><p>Selects from a set of channel operations.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.SelectTimeoutError.html" title="crossbeam_channel::SelectTimeoutError struct">SelectTimeoutError</a></div><div class="item-right docblock-short"><p>An error returned from the <a href="struct.Select.html#method.select_timeout"><code>select_timeout</code></a> method.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.SelectedOperation.html" title="crossbeam_channel::SelectedOperation struct">SelectedOperation</a></div><div class="item-right docblock-short"><p>A selected operation that needs to be completed.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.SendError.html" title="crossbeam_channel::SendError struct">SendError</a></div><div class="item-right docblock-short"><p>An error returned from the <a href="struct.Sender.html#method.send"><code>send</code></a> method.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.Sender.html" title="crossbeam_channel::Sender struct">Sender</a></div><div class="item-right docblock-short"><p>The sending side of a channel.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.TryIter.html" title="crossbeam_channel::TryIter struct">TryIter</a></div><div class="item-right docblock-short"><p>A non-blocking iterator over messages in a channel.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.TryReadyError.html" title="crossbeam_channel::TryReadyError struct">TryReadyError</a></div><div class="item-right docblock-short"><p>An error returned from the <a href="struct.Select.html#method.try_ready"><code>try_ready</code></a> method.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="struct" href="struct.TrySelectError.html" title="crossbeam_channel::TrySelectError struct">TrySelectError</a></div><div class="item-right docblock-short"><p>An error returned from the <a href="struct.Select.html#method.try_select"><code>try_select</code></a> method.</p>
</div></div></div><h2 id="enums" class="small-section-header"><a href="#enums">Enums</a></h2>
<div class="item-table"><div class="item-row"><div class="item-left module-item"><a class="enum" href="enum.RecvTimeoutError.html" title="crossbeam_channel::RecvTimeoutError enum">RecvTimeoutError</a></div><div class="item-right docblock-short"><p>An error returned from the <a href="struct.Receiver.html#method.recv_timeout"><code>recv_timeout</code></a> method.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="enum" href="enum.SendTimeoutError.html" title="crossbeam_channel::SendTimeoutError enum">SendTimeoutError</a></div><div class="item-right docblock-short"><p>An error returned from the <a href="struct.Sender.html#method.send_timeout"><code>send_timeout</code></a> method.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="enum" href="enum.TryRecvError.html" title="crossbeam_channel::TryRecvError enum">TryRecvError</a></div><div class="item-right docblock-short"><p>An error returned from the <a href="struct.Receiver.html#method.try_recv"><code>try_recv</code></a> method.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="enum" href="enum.TrySendError.html" title="crossbeam_channel::TrySendError enum">TrySendError</a></div><div class="item-right docblock-short"><p>An error returned from the <a href="struct.Sender.html#method.try_send"><code>try_send</code></a> method.</p>
</div></div></div><h2 id="functions" class="small-section-header"><a href="#functions">Functions</a></h2>
<div class="item-table"><div class="item-row"><div class="item-left module-item"><a class="fn" href="fn.after.html" title="crossbeam_channel::after fn">after</a></div><div class="item-right docblock-short"><p>Creates a receiver that delivers a message after a certain duration of time.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="fn" href="fn.at.html" title="crossbeam_channel::at fn">at</a></div><div class="item-right docblock-short"><p>Creates a receiver that delivers a message at a certain instant in time.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="fn" href="fn.bounded.html" title="crossbeam_channel::bounded fn">bounded</a></div><div class="item-right docblock-short"><p>Creates a channel of bounded capacity.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="fn" href="fn.never.html" title="crossbeam_channel::never fn">never</a></div><div class="item-right docblock-short"><p>Creates a receiver that never delivers messages.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="fn" href="fn.tick.html" title="crossbeam_channel::tick fn">tick</a></div><div class="item-right docblock-short"><p>Creates a receiver that delivers messages periodically.</p>
</div></div><div class="item-row"><div class="item-left module-item"><a class="fn" href="fn.unbounded.html" title="crossbeam_channel::unbounded fn">unbounded</a></div><div class="item-right docblock-short"><p>Creates a channel of unbounded capacity.</p>
</div></div></div></section><section id="search" class="content hidden"></section></div></main><div id="rustdoc-vars" data-root-path="../" data-current-crate="crossbeam_channel" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.59.0 (9d1b2106e 2022-02-23)" ></div>
</body></html>