# [−] [src] Module tokio::runtime

The Tokio runtime.

Unlike other Rust programs, asynchronous applications require runtime support. In particular, the following runtime services are necessary:

- An I/O event loop, called the driver, which drives I/O resources and dispatches I/O events to tasks that depend on them.
- A scheduler to execute tasks that use these I/O resources.
- A timer for scheduling work to run after a set period of time.

Tokio's `Runtime` bundles all of these services as a single type, allowing them to be started, shut down, and configured together. However, often it is not required to configure a `Runtime` manually, and user may just use the `tokio::main` attribute macro, which creates a `Runtime` under the hood.

# Usage

When no fine tuning is required, the `tokio::main` attribute macro can be used.

    use tokio::net::TcpListener;
    use tokio::io::{AsyncReadExt, AsyncWriteExt};

    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let listener = TcpListener::bind("127.0.0.1:8080").await?;

        loop {
            let (mut socket, _) = listener.accept().await?;

            tokio::spawn(async move {
                let mut buf = [0; 1024];

                // In a loop, read data from the socket and write the data back.
                loop {
                    let n = match socket.read(&mut buf).await {
                        // socket closed
                        Ok(n) if n == 0 => return,
                        Ok(n) => n,
                        Err(e) => {
                            println!("failed to read from socket; err = {:?}", e);
                            return;
                        }
                    };

                    // Write the data back
                    if let Err(e) = socket.write_all(&buf[0..n]).await {
                        println!("failed to write to socket; err = {:?}", e);
                        return;
                    }
                }
            });
        }
    }

From within the context of the runtime, additional tasks are spawned using the `tokio::spawn` function. Futures spawned using this function will be executed on the same thread pool used by the `Runtime`.

A `Runtime` instance can also be used directly.

    use tokio::net::TcpListener;
    use tokio::io::{AsyncReadExt, AsyncWriteExt};
    use tokio::runtime::Runtime;

    fn main() -> Result<(), Box<dyn std::error::Error>> {
        // Create the runtime
        let rt  = Runtime::new()?;

        // Spawn the root task
        rt.block_on(async {
            let listener = TcpListener::bind("127.0.0.1:8080").await?;

            loop {
                let (mut socket, _) = listener.accept().await?;

                tokio::spawn(async move {
                    let mut buf = [0; 1024];

                    // In a loop, read data from the socket and write the data back.
                    loop {
                        let n = match socket.read(&mut buf).await {
                            // socket closed
                            Ok(n) if n == 0 => return,
                            Ok(n) => n,
                            Err(e) => {
                                println!("failed to read from socket; err = {:?}", e);
                                return;
                            }
                        };

                        // Write the data back
                        if let Err(e) = socket.write_all(&buf[0..n]).await {
                            println!("failed to write to socket; err = {:?}", e);
                            return;
                        }
                    }
                });
            }
        })
    }

## Runtime Configurations

Tokio provides multiple task scheduling strategies, suitable for different applications. The runtime builder or `#[tokio::main]` attribute may be used to select which scheduler to use.

#### Multi-Thread Scheduler

The multi-thread scheduler executes futures on a thread pool, using a work-stealing strategy. By default, it will start a worker thread for each CPU core available on the system. This tends to be the ideal configurations for most applications. The multi-thread scheduler requires the `rt-multi-thread` feature flag, and is selected by default:

    use tokio::runtime;

    let threaded_rt = runtime::Runtime::new()?;

Most applications should use the multi-thread scheduler, except in some niche use-cases, such as when running only a single thread is required.

#### Current-Thread Scheduler

The current-thread scheduler provides a single-threaded future executor. All tasks will be created and executed on the current thread. This requires the `rt` feature flag.

    use tokio::runtime;

    let basic_rt = runtime::Builder::new_current_thread()
        .build()?;

#### Resource drivers

When configuring a runtime by hand, no resource drivers are enabled by default. In this case, attempting to use networking types or time types will fail. In order to enable these types, the resource drivers must be enabled. This is done with `Builder::enable_io` and `Builder::enable_time`. As a shorthand, `Builder::enable_all` enables both resource drivers.

## Lifetime of spawned threads

The runtime may spawn threads depending on its configuration and usage. The multi-thread scheduler spawns threads to schedule tasks and for `spawn_blocking` calls.

While the `Runtime` is active, threads may shutdown after periods of being idle. Once `Runtime` is dropped, all runtime threads are forcibly shutdown. Any tasks that have not yet completed will be dropped.

## Structs

Builder | Builds Tokio Runtime with custom configuration values.
EnterGuard | Runtime context guard.
Handle | Handle to the runtime.
Runtime | The Tokio runtime.