Sophie

Sophie

distrib > Mageia > 6 > x86_64 > media > core-updates > by-pkgid > 878cdd00a13d17a73c6619a777ef5d74 > files > 314

rust-doc-1.19.0-1.mga6.x86_64.rpm

<!DOCTYPE HTML>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Designing the Thread Pool Interface - The Rust Programming Language</title>
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <base href="">

        <link rel="stylesheet" href="book.css">
        <link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>

        <link rel="shortcut icon" href="favicon.png">

        <!-- Font Awesome -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

        <link rel="stylesheet" href="highlight.css">
        <link rel="stylesheet" href="tomorrow-night.css">
        <style>
            .page-wrapper.has-warning > .nav-chapters {
              /* add height for warning content & margin */
              top: 120px;
            }

            p.warning {
                background-color: rgb(242, 222, 222);
                border-bottom-color: rgb(238, 211, 215);
                border-bottom-left-radius: 4px;
                border-bottom-right-radius: 4px;
                border-bottom-style: solid;
                border-bottom-width: 0.666667px;
                border-image-outset: 0 0 0 0;
                border-image-repeat: stretch stretch;
                border-image-slice: 100% 100% 100% 100%;
                border-image-source: none;
                border-image-width: 1 1 1 1;
                border-left-color: rgb(238, 211, 215);
                border-left-style: solid;
                border-left-width: 0.666667px;
                border-right-color: rgb(238, 211, 215);
                border-right-style: solid;
                border-right-width: 0.666667px;
                border-top-color: rgb(238, 211, 215);
                border-top-left-radius: 4px;
                border-top-right-radius: 4px;
                border-top-style: solid;
                border-top-width: 0.666667px;
                color: rgb(185, 74, 72);
                margin-bottom: 0px;
                margin-left: 0px;
                margin-right: 0px;
                margin-top: 30px;
                padding-bottom: 8px;
                padding-left: 14px;
                padding-right: 35px;
                padding-top: 8px;
            }
            p.warning strong {
                color: rgb(185, 74, 72)
            }
            p.warning a {
                color: rgb(0, 136, 204)
            }
        </style>

        <!-- MathJax -->
        <script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

        <!-- Fetch JQuery from CDN but have a local fallback -->
        <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
        <script>
            if (typeof jQuery == 'undefined') {
                document.write(unescape("%3Cscript src='jquery.js'%3E%3C/script%3E"));
            }
        </script>
    </head>
    <body class="light">
        <!-- Set the theme before any content is loaded, prevents flash -->
        <script type="text/javascript">
            var theme = localStorage.getItem('theme');
            if (theme == null) { theme = 'light'; }
            $('body').removeClass().addClass(theme);
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script type="text/javascript">
            var sidebar = localStorage.getItem('sidebar');
            if (sidebar === "hidden") { $("html").addClass("sidebar-hidden") }
            else if (sidebar === "visible") { $("html").addClass("sidebar-visible") }
        </script>

        <div id="sidebar" class="sidebar">
            <ul class="chapter"><li><a href="ch01-00-introduction.html"><strong>1.</strong> Introduction</a></li><li><ul class="section"><li><a href="ch01-01-installation.html"><strong>1.1.</strong> Installation</a></li><li><a href="ch01-02-hello-world.html"><strong>1.2.</strong> Hello, World!</a></li></ul></li><li><a href="ch02-00-guessing-game-tutorial.html"><strong>2.</strong> Guessing Game Tutorial</a></li><li><a href="ch03-00-common-programming-concepts.html"><strong>3.</strong> Common Programming Concepts</a></li><li><ul class="section"><li><a href="ch03-01-variables-and-mutability.html"><strong>3.1.</strong> Variables and Mutability</a></li><li><a href="ch03-02-data-types.html"><strong>3.2.</strong> Data Types</a></li><li><a href="ch03-03-how-functions-work.html"><strong>3.3.</strong> How Functions Work</a></li><li><a href="ch03-04-comments.html"><strong>3.4.</strong> Comments</a></li><li><a href="ch03-05-control-flow.html"><strong>3.5.</strong> Control Flow</a></li></ul></li><li><a href="ch04-00-understanding-ownership.html"><strong>4.</strong> Understanding Ownership</a></li><li><ul class="section"><li><a href="ch04-01-what-is-ownership.html"><strong>4.1.</strong> What is Ownership?</a></li><li><a href="ch04-02-references-and-borrowing.html"><strong>4.2.</strong> References &amp; Borrowing</a></li><li><a href="ch04-03-slices.html"><strong>4.3.</strong> Slices</a></li></ul></li><li><a href="ch05-00-structs.html"><strong>5.</strong> Using Structs to Structure Related Data</a></li><li><ul class="section"><li><a href="ch05-01-defining-structs.html"><strong>5.1.</strong> Defining and Instantiating Structs</a></li><li><a href="ch05-02-example-structs.html"><strong>5.2.</strong> An Example Program Using Structs</a></li><li><a href="ch05-03-method-syntax.html"><strong>5.3.</strong> Method Syntax</a></li></ul></li><li><a href="ch06-00-enums.html"><strong>6.</strong> Enums and Pattern Matching</a></li><li><ul class="section"><li><a href="ch06-01-defining-an-enum.html"><strong>6.1.</strong> Defining an Enum</a></li><li><a href="ch06-02-match.html"><strong>6.2.</strong> The <code>match</code> Control Flow Operator</a></li><li><a href="ch06-03-if-let.html"><strong>6.3.</strong> Concise Control Flow with <code>if let</code></a></li></ul></li><li><a href="ch07-00-modules.html"><strong>7.</strong> Modules</a></li><li><ul class="section"><li><a href="ch07-01-mod-and-the-filesystem.html"><strong>7.1.</strong> <code>mod</code> and the Filesystem</a></li><li><a href="ch07-02-controlling-visibility-with-pub.html"><strong>7.2.</strong> Controlling Visibility with <code>pub</code></a></li><li><a href="ch07-03-importing-names-with-use.html"><strong>7.3.</strong> Importing Names with <code>use</code></a></li></ul></li><li><a href="ch08-00-common-collections.html"><strong>8.</strong> Common Collections</a></li><li><ul class="section"><li><a href="ch08-01-vectors.html"><strong>8.1.</strong> Vectors</a></li><li><a href="ch08-02-strings.html"><strong>8.2.</strong> Strings</a></li><li><a href="ch08-03-hash-maps.html"><strong>8.3.</strong> Hash Maps</a></li></ul></li><li><a href="ch09-00-error-handling.html"><strong>9.</strong> Error Handling</a></li><li><ul class="section"><li><a href="ch09-01-unrecoverable-errors-with-panic.html"><strong>9.1.</strong> Unrecoverable Errors with <code>panic!</code></a></li><li><a href="ch09-02-recoverable-errors-with-result.html"><strong>9.2.</strong> Recoverable Errors with <code>Result</code></a></li><li><a href="ch09-03-to-panic-or-not-to-panic.html"><strong>9.3.</strong> To <code>panic!</code> or Not To <code>panic!</code></a></li></ul></li><li><a href="ch10-00-generics.html"><strong>10.</strong> Generic Types, Traits, and Lifetimes</a></li><li><ul class="section"><li><a href="ch10-01-syntax.html"><strong>10.1.</strong> Generic Data Types</a></li><li><a href="ch10-02-traits.html"><strong>10.2.</strong> Traits: Defining Shared Behavior</a></li><li><a href="ch10-03-lifetime-syntax.html"><strong>10.3.</strong> Validating References with Lifetimes</a></li></ul></li><li><a href="ch11-00-testing.html"><strong>11.</strong> Testing</a></li><li><ul class="section"><li><a href="ch11-01-writing-tests.html"><strong>11.1.</strong> Writing tests</a></li><li><a href="ch11-02-running-tests.html"><strong>11.2.</strong> Running tests</a></li><li><a href="ch11-03-test-organization.html"><strong>11.3.</strong> Test Organization</a></li></ul></li><li><a href="ch12-00-an-io-project.html"><strong>12.</strong> An I/O Project</a></li><li><ul class="section"><li><a href="ch12-01-accepting-command-line-arguments.html"><strong>12.1.</strong> Accepting Command Line Arguments</a></li><li><a href="ch12-02-reading-a-file.html"><strong>12.2.</strong> Reading a File</a></li><li><a href="ch12-03-improving-error-handling-and-modularity.html"><strong>12.3.</strong> Improving Error Handling and Modularity</a></li><li><a href="ch12-04-testing-the-librarys-functionality.html"><strong>12.4.</strong> Testing the Library's Functionality</a></li><li><a href="ch12-05-working-with-environment-variables.html"><strong>12.5.</strong> Working with Environment Variables</a></li><li><a href="ch12-06-writing-to-stderr-instead-of-stdout.html"><strong>12.6.</strong> Writing to <code>stderr</code> instead of <code>stdout</code></a></li></ul></li><li><a href="ch13-00-functional-features.html"><strong>13.</strong> Functional Language Features in Rust</a></li><li><ul class="section"><li><a href="ch13-01-closures.html"><strong>13.1.</strong> Closures</a></li><li><a href="ch13-02-iterators.html"><strong>13.2.</strong> Iterators</a></li><li><a href="ch13-03-improving-our-io-project.html"><strong>13.3.</strong> Improving our I/O Project</a></li><li><a href="ch13-04-performance.html"><strong>13.4.</strong> Performance</a></li></ul></li><li><a href="ch14-00-more-about-cargo.html"><strong>14.</strong> More about Cargo and Crates.io</a></li><li><ul class="section"><li><a href="ch14-01-release-profiles.html"><strong>14.1.</strong> Release Profiles</a></li><li><a href="ch14-02-publishing-to-crates-io.html"><strong>14.2.</strong> Publishing a Crate to Crates.io</a></li><li><a href="ch14-03-cargo-workspaces.html"><strong>14.3.</strong> Cargo Workspaces</a></li><li><a href="ch14-04-installing-binaries.html"><strong>14.4.</strong> Installing Binaries from Crates.io with <code>cargo install</code></a></li><li><a href="ch14-05-extending-cargo.html"><strong>14.5.</strong> Extending Cargo with Custom Commands</a></li></ul></li><li><a href="ch15-00-smart-pointers.html"><strong>15.</strong> Smart Pointers</a></li><li><ul class="section"><li><a href="ch15-01-box.html"><strong>15.1.</strong> <code>Box&lt;T&gt;</code> Points to Data on the Heap and Has a Known Size</a></li><li><a href="ch15-02-deref.html"><strong>15.2.</strong> The <code>Deref</code> Trait Allows Access to the Data Through a Reference</a></li><li><a href="ch15-03-drop.html"><strong>15.3.</strong> The <code>Drop</code> Trait Runs Code on Cleanup</a></li><li><a href="ch15-04-rc.html"><strong>15.4.</strong> <code>Rc&lt;T&gt;</code>, the Reference Counted Smart Pointer</a></li><li><a href="ch15-05-interior-mutability.html"><strong>15.5.</strong> <code>RefCell&lt;T&gt;</code> and the Interior Mutability Pattern</a></li><li><a href="ch15-06-reference-cycles.html"><strong>15.6.</strong> Creating Reference Cycles and Leaking Memory is Safe</a></li></ul></li><li><a href="ch16-00-concurrency.html"><strong>16.</strong> Fearless Concurrency</a></li><li><ul class="section"><li><a href="ch16-01-threads.html"><strong>16.1.</strong> Threads</a></li><li><a href="ch16-02-message-passing.html"><strong>16.2.</strong> Message Passing</a></li><li><a href="ch16-03-shared-state.html"><strong>16.3.</strong> Shared State</a></li><li><a href="ch16-04-extensible-concurrency-sync-and-send.html"><strong>16.4.</strong> Extensible Concurrency: <code>Sync</code> and <code>Send</code></a></li></ul></li><li><a href="ch17-00-oop.html"><strong>17.</strong> Is Rust an Object-Oriented Programming Language?</a></li><li><ul class="section"><li><a href="ch17-01-what-is-oo.html"><strong>17.1.</strong> What Does Object-Oriented Mean?</a></li><li><a href="ch17-02-trait-objects.html"><strong>17.2.</strong> Trait Objects for Using Values of Different Types</a></li><li><a href="ch17-03-oo-design-patterns.html"><strong>17.3.</strong> Object-Oriented Design Pattern Implementations</a></li></ul></li><li><a href="ch18-00-patterns.html"><strong>18.</strong> Patterns Match the Structure of Values</a></li><li><ul class="section"><li><a href="ch18-01-all-the-places-for-patterns.html"><strong>18.1.</strong> All the Places Patterns May be Used</a></li><li><a href="ch18-02-refutability.html"><strong>18.2.</strong> Refutability: Whether a Pattern Might Fail to Match</a></li><li><a href="ch18-03-pattern-syntax.html"><strong>18.3.</strong> All the Pattern Syntax</a></li></ul></li><li><a href="ch19-00-advanced-features.html"><strong>19.</strong> Advanced Features</a></li><li><ul class="section"><li><a href="ch19-01-unsafe-rust.html"><strong>19.1.</strong> Unsafe Rust</a></li><li><a href="ch19-02-advanced-lifetimes.html"><strong>19.2.</strong> Advanced Lifetimes</a></li><li><a href="ch19-03-advanced-traits.html"><strong>19.3.</strong> Advanced Traits</a></li><li><a href="ch19-04-advanced-types.html"><strong>19.4.</strong> Advanced Types</a></li><li><a href="ch19-05-advanced-functions-and-closures.html"><strong>19.5.</strong> Advanced Functions &amp; Closures</a></li></ul></li><li><a href="ch20-00-final-project-a-web-server.html"><strong>20.</strong> Final Project: Building a Multithreaded Web Server</a></li><li><ul class="section"><li><a href="ch20-01-single-threaded.html"><strong>20.1.</strong> A Single Threaded Web Server</a></li><li><a href="ch20-02-slow-requests.html"><strong>20.2.</strong> How Slow Requests Affect Throughput</a></li><li><a href="ch20-03-designing-the-interface.html" class="active"><strong>20.3.</strong> Designing the Thread Pool Interface</a></li><li><a href="ch20-04-storing-threads.html"><strong>20.4.</strong> Creating the Thread Pool and Storing Threads</a></li><li><a href="ch20-05-sending-requests-via-channels.html"><strong>20.5.</strong> Sending Requests to Threads Via Channels</a></li><li><a href="ch20-06-graceful-shutdown-and-cleanup.html"><strong>20.6.</strong> Graceful Shutdown and Cleanup</a></li></ul></li><li><a href="appendix-00.html"><strong>21.</strong> Appendix</a></li><li><ul class="section"><li><a href="appendix-01-keywords.html"><strong>21.1.</strong> A - Keywords</a></li><li><a href="appendix-02-operators.html"><strong>21.2.</strong> B - Operators</a></li><li><strong>21.3.</strong> C - Derivable Traits</li><li><strong>21.4.</strong> D - Nightly Rust</li><li><strong>21.5.</strong> E - Macros</li><li><strong>21.6.</strong> F - Translations</li><li><a href="appendix-07-newest-features.html"><strong>21.7.</strong> G - Newest Features</a></li></ul></li></ul>
        </div>

        <div id="page-wrapper" class="page-wrapper has-warning">

            <div class="page">
                <header><p class="warning">You are reading a <strong>draft</strong> of the next edition of TRPL. For more, go <a href="../index.html">here</a>.</p></header>
                <div id="menu-bar" class="menu-bar">
                    <div class="left-buttons">
                        <i id="sidebar-toggle" class="fa fa-bars"></i>
                        <i id="theme-toggle" class="fa fa-paint-brush"></i>
                    </div>

                    <h1 class="menu-title">The Rust Programming Language</h1>

                    <div class="right-buttons">
                        <i id="print-button" class="fa fa-print" title="Print this book"></i>
                    </div>
                </div>


                <div id="content" class="content">
                    <a class="header" href="ch20-03-designing-the-interface.html#designing-the-thread-pool-interface" id="designing-the-thread-pool-interface"><h2>Designing the Thread Pool Interface</h2></a>
<p>Let's talk about what using the pool should look like. The authors often find
that when trying to design some code, writing the client interface first can
really help guide your design. Write the API of the code to be structured in
the way you'd want to call it, then implement the functionality within that
structure rather than implementing the functionality then designing the public
API.</p>
<p>Similar to how we used Test Driven Development in the project in Chapter 12,
we're going to use Compiler Driven Development here. We're going to write the
code that calls the functions we wish we had, then we'll lean on the compiler
to tell us what we should change next. The compiler error messages will guide
our implementation.</p>
<a class="header" href="ch20-03-designing-the-interface.html#code-structure-if-we-could-use-threadspawn" id="code-structure-if-we-could-use-threadspawn"><h3>Code Structure if We Could Use <code>thread::spawn</code></h3></a>
<p>First, let's explore what the code to create a new thread for every connection
could look like. This isn't our final plan due to the problems with potentially
spawning an unlimited number of threads that we talked about earlier, but it's
a start. Listing 20-11 shows the changes to <code>main</code> to spawn a new thread to
handle each stream within the <code>for</code> loop:</p>
<p><span class="filename">Filename: src/main.rs</span></p>
<pre><pre class="playpen"><code class="language-rust no_run"># use std::thread;
# use std::io::prelude::*;
# use std::net::TcpListener;
# use std::net::TcpStream;
#
fn main() {
    let listener = TcpListener::bind(&quot;127.0.0.1:8080&quot;).unwrap();

    for stream in listener.incoming() {
        let stream = stream.unwrap();

        thread::spawn(|| {
            handle_connection(stream);
        });
    }
}
# fn handle_connection(mut stream: TcpStream) {}
</code></pre></pre>
<p><span class="caption">Listing 20-11: Spawning a new thread for each
stream</span></p>
<p>As we learned in Chapter 16, <code>thread::spawn</code> will create a new thread and then
run the code in the closure in it. If you run this code and load <code>/sleep</code> and
then <code>/</code> in two browser tabs, you'll indeed see the request to <code>/</code> doesn't have
to wait for <code>/sleep</code> to finish. But as we mentioned, this will eventually
overwhelm the system since we're making new threads without any limit.</p>
<a class="header" href="ch20-03-designing-the-interface.html#creating-a-similar-interface-for-threadpool" id="creating-a-similar-interface-for-threadpool"><h3>Creating a Similar Interface for <code>ThreadPool</code></h3></a>
<p>We want our thread pool to work in a similar, familiar way so that switching
from threads to a thread pool doesn't require large changes to the code we want
to run in the pool. Listing 20-12 shows the hypothetical interface for a
<code>ThreadPool</code> struct we'd like to use instead of <code>thread::spawn</code>:</p>
<p><span class="filename">Filename: src/main.rs</span></p>
<pre><pre class="playpen"><code class="language-rust no_run"># use std::thread;
# use std::io::prelude::*;
# use std::net::TcpListener;
# use std::net::TcpStream;
# struct ThreadPool;
# impl ThreadPool {
#    fn new(size: u32) -&gt; ThreadPool { ThreadPool }
#    fn execute&lt;F&gt;(&amp;self, f: F)
#        where F: FnOnce() + Send + 'static {}
# }
#
fn main() {
    let listener = TcpListener::bind(&quot;127.0.0.1:8080&quot;).unwrap();
    let pool = ThreadPool::new(4);

    for stream in listener.incoming() {
        let stream = stream.unwrap();

        pool.execute(|| {
            handle_connection(stream);
        });
    }
}
# fn handle_connection(mut stream: TcpStream) {}
</code></pre></pre>
<p><span class="caption">Listing 20-12: How we want to be able to use the
<code>ThreadPool</code> we're going to implement</span></p>
<p>We use <code>ThreadPool::new</code> to create a new thread pool with a configurable number
of threads, in this case four. Then, in the <code>for</code> loop, <code>pool.execute</code> will
work in a similar way to <code>thread::spawn</code>.</p>
<a class="header" href="ch20-03-designing-the-interface.html#compiler-driven-development-to-get-the-api-compiling" id="compiler-driven-development-to-get-the-api-compiling"><h3>Compiler Driven Development to Get the API Compiling</h3></a>
<p>Go ahead and make the changes in Listing 20-12 to <em>src/main.rs</em>, and let's use
the compiler errors to drive our development. Here's the first error we get:</p>
<pre><code class="language-text">$ cargo check
   Compiling hello v0.1.0 (file:///projects/hello)
error[E0433]: failed to resolve. Use of undeclared type or module `ThreadPool`
  --&gt; src\main.rs:10:16
   |
10 |     let pool = ThreadPool::new(4);
   |                ^^^^^^^^^^^^^^^ Use of undeclared type or module
   `ThreadPool`

error: aborting due to previous error
</code></pre>
<p>Great, we need a <code>ThreadPool</code>. Let's switch the <code>hello</code> crate from a binary
crate to a library crate to hold our <code>ThreadPool</code> implementation, since the
thread pool implementation will be independent of the particular kind of work
that we're doing in our web server. Once we've got the thread pool library
written, we could use that functionality to do whatever work we want to do, not
just serve web requests.</p>
<p>So create <em>src/lib.rs</em> that contains the simplest definition of a <code>ThreadPool</code>
struct that we can have for now:</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
pub struct ThreadPool;

#}</code></pre></pre>
<p>Then create a new directory, <em>src/bin</em>, and move the binary crate rooted in
<em>src/main.rs</em> into <em>src/bin/main.rs</em>. This will make the library crate be the
primary crate in the <em>hello</em> directory; we can still run the binary in
<em>src/bin/main.rs</em> using <code>cargo run</code> though. After moving the <em>main.rs</em> file,
edit it to bring the library crate in and bring <code>ThreadPool</code> into scope by
adding this at the top of <em>src/bin/main.rs</em>:</p>
<p><span class="filename">Filename: src/bin/main.rs</span></p>
<pre><code class="language-rust ignore">extern crate hello;
use hello::ThreadPool;
</code></pre>
<p>And try again in order to get the next error that we need to address:</p>
<pre><code class="language-text">$ cargo check
   Compiling hello v0.1.0 (file:///projects/hello)
error: no associated item named `new` found for type `hello::ThreadPool` in the
current scope
  --&gt; src\main.rs:13:16
   |
13 |     let pool = ThreadPool::new(4);
   |                ^^^^^^^^^^^^^^^
   |
</code></pre>
<p>Cool, the next thing is to create an associated function named <code>new</code> for
<code>ThreadPool</code>. We also know that <code>new</code> needs to have one parameter that can
accept <code>4</code> as an argument, and <code>new</code> should return a <code>ThreadPool</code> instance.
Let's implement the simplest <code>new</code> function that will have those
characteristics:</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
pub struct ThreadPool;

impl ThreadPool {
    pub fn new(size: u32) -&gt; ThreadPool {
        ThreadPool
    }
}

#}</code></pre></pre>
<p>We picked <code>u32</code> as the type of the <code>size</code> parameter, since we know that a
negative number of threads makes no sense. <code>u32</code> is a solid default. Once we
actually implement <code>new</code> for real, we'll reconsider whether this is the right
choice for what the implementation needs, but for now, we're just working
through compiler errors.</p>
<p>Let's check the code again:</p>
<pre><code class="language-text">$ cargo check
   Compiling hello v0.1.0 (file:///projects/hello)
warning: unused variable: `size`, #[warn(unused_variables)] on by default
 --&gt; src/lib.rs:4:16
  |
4 |     pub fn new(size: u32) -&gt; ThreadPool {
  |                ^^^^

error: no method named `execute` found for type `hello::ThreadPool` in the
current scope
  --&gt; src/main.rs:18:14
   |
18 |         pool.execute(|| {
   |              ^^^^^^^
</code></pre>
<p>Okay, a warning and an error. Ignoring the warning for a moment, the error is
because we don't have an <code>execute</code> method on <code>ThreadPool</code>. Let's define one,
and we need it to take a closure. If you remember from Chapter 13, we can take
closures as arguments with three different traits: <code>Fn</code>, <code>FnMut</code>, and <code>FnOnce</code>.
What kind of closure should we use? Well, we know we're going to end up doing
something similar to <code>thread::spawn</code>; what bounds does the signature of
<code>thread::spawn</code> have on its argument? Let's look at the documentation, which
says:</p>
<pre><code class="language-rust ignore">pub fn spawn&lt;F, T&gt;(f: F) -&gt; JoinHandle&lt;T&gt;
    where
        F: FnOnce() -&gt; T + Send + 'static,
        T: Send + 'static
</code></pre>
<p><code>F</code> is the parameter we care about here; <code>T</code> is related to the return value and
we're not concerned with that. Given that <code>spawn</code> uses <code>FnOnce</code> as the trait
bound on <code>F</code>, it's probably what we want as well, since we'll eventually be
passing the argument we get in <code>execute</code> to <code>spawn</code>. We can be further
confident that <code>FnOnce</code> is the trait that we want to use since the thread for
running a request is only going to execute that request's closure one time.</p>
<p><code>F</code> also has the trait bound <code>Send</code> and the lifetime bound <code>'static</code>, which
also make sense for our situation: we need <code>Send</code> to transfer the closure from
one thread to another, and <code>'static</code> because we don't know how long the thread
will execute. Let's create an <code>execute</code> method on <code>ThreadPool</code> that will take a
generic parameter <code>F</code> with these bounds:</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
# pub struct ThreadPool;
impl ThreadPool {
    // ...snip...

    pub fn execute&lt;F&gt;(&amp;self, f: F)
        where
            F: FnOnce() + Send + 'static
    {

    }
}

#}</code></pre></pre>
<p>The <code>FnOnce</code> trait still needs the <code>()</code> after it since this <code>FnOnce</code> is
representing a closure that takes no parameters and doesn't return a value.
Just like function definitions, the return type can be omitted from the
signature, but even if we have no parameters, we still need the parentheses.</p>
<p>Again, since we're working on getting the interface compiling, we're adding the
simplest implementation of the <code>execute</code> method, which does nothing. Let's
check again:</p>
<pre><code class="language-text">$ cargo check
   Compiling hello v0.1.0 (file:///projects/hello)
warning: unused variable: `size`, #[warn(unused_variables)] on by default
 --&gt; src/lib.rs:4:16
  |
4 |     pub fn new(size: u32) -&gt; ThreadPool {
  |                ^^^^

warning: unused variable: `f`, #[warn(unused_variables)] on by default
 --&gt; src/lib.rs:8:30
  |
8 |     pub fn execute&lt;F&gt;(&amp;self, f: F)
  |                              ^
</code></pre>
<p>Only warnings now! It compiles! Note that if you try <code>cargo run</code> and making a
request in the browser, though, you'll see the errors in the browser again that
we saw in the beginning of the chapter. Our library isn't actually calling the
closure passed to <code>execute</code> yet!</p>
<blockquote>
<p>A saying you might hear about languages with strict compilers like Haskell
and Rust is &quot;if the code compiles, it works.&quot; This is a good time to remember
that this is just a phrase and a feeling people sometimes have, it's not
actually universally true. Our project compiles, but it does absolutely
nothing! If we were building a real, complete project, this would be a great
time to start writing unit tests to check that the code compiles <em>and</em> has
the behavior we want.</p>
</blockquote>

                </div>

                <!-- Mobile navigation buttons -->
                
                    <a href="ch20-02-slow-requests.html" class="mobile-nav-chapters previous">
                        <i class="fa fa-angle-left"></i>
                    </a>
                

                
                    <a href="ch20-04-storing-threads.html" class="mobile-nav-chapters next">
                        <i class="fa fa-angle-right"></i>
                    </a>
                

            </div>

            
                <a href="ch20-02-slow-requests.html" class="nav-chapters previous" title="You can navigate through the chapters using the arrow keys">
                    <i class="fa fa-angle-left"></i>
                </a>
            

            
                <a href="ch20-04-storing-threads.html" class="nav-chapters next" title="You can navigate through the chapters using the arrow keys">
                    <i class="fa fa-angle-right"></i>
                </a>
            

        </div>


        <!-- Local fallback for Font Awesome -->
        <script>
            if ($(".fa").css("font-family") !== "FontAwesome") {
                $('<link rel="stylesheet" type="text/css" href="_FontAwesome/css/font-awesome.css">').prependTo('head');
            }
        </script>

        <!-- Livereload script (if served using the cli tool) -->
        

        <script src="highlight.js"></script>
        <script src="book.js"></script>
    </body>
</html>