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

Asynchronous green-threads.

## What are Tasks?

A task is a light weight, non-blocking unit of execution. A task is similar to an OS thread, but rather than being managed by the OS scheduler, they are managed by the Tokio runtime. Another name for this general pattern is green threads. If you are familiar with Go's goroutines, Kotlin's coroutines, or Erlang's processes, you can think of Tokio's tasks as something similar.

Key points about tasks include:

- Tasks are light weight. Because tasks are scheduled by the Tokio runtime rather than the operating system, creating new tasks or switching between tasks does not require a context switch and has fairly low overhead. Creating, running, and destroying large numbers of tasks is quite cheap, especially compared to OS threads.

- Tasks are scheduled cooperatively. Most operating systems implement preemptive multitasking. This is a scheduling technique where the operating system allows each thread to run for a period of time, and then preempts it, temporarily pausing that thread and switching to another. Tasks, on the other hand, implement cooperative multitasking. In cooperative multitasking, a task is allowed to run until it yields, indicating to the Tokio runtime's scheduler that it cannot currently continue executing. When a task yields, the Tokio runtime switches to executing the next task.

- Tasks are non-blocking. Typically, when an OS thread performs I/O or must synchronize with another thread, it blocks, allowing the OS to schedule another thread. When a task cannot continue executing, it must yield instead, allowing the Tokio runtime to schedule another task. Tasks should generally not perform system calls or other operations that could block a thread, as this would prevent other tasks running on the same thread from executing as well. Instead, this module provides APIs for running blocking operations in an asynchronous context.

## Working with Tasks

This module provides the following APIs for working with tasks:

### Spawning

Perhaps the most important function in this module is `task::spawn`. This function can be thought of as an async equivalent to the standard library's `thread::spawn`. It takes an `async` block or other future, and creates a new task to run that work concurrently:

    use tokio::task;

    task::spawn(async {
        // perform some work here...
    });

Like `std::thread::spawn`, `task::spawn` returns a `JoinHandle` struct. A `JoinHandle` is itself a future which may be used to await the output of the spawned task. For example:

    use tokio::task;

    let join = task::spawn(async {
        // ...
        "hello world!"
    });

    // ...

    // Await the result of the spawned task.
    let result = join.await?;
    assert_eq!(result, "hello world!");

Again, like `std::thread`'s `JoinHandle` type, if the spawned task panics, awaiting its `JoinHandle` will return a `JoinError``. For example:

    use tokio::task;

    let join = task::spawn(async {
        panic!("something bad happened!")
    });

    // The returned result indicates that the task failed.
    assert!(join.await.is_err());

`spawn`, `JoinHandle`, and `JoinError` are present when the "rt" feature flag is enabled.

### Blocking and Yielding

As we discussed above, code running in asynchronous tasks should not perform operations that can block. A blocking operation performed in a task running on a thread that is also running other tasks would block the entire thread, preventing other tasks from running.

Instead, Tokio provides two APIs for running blocking operations in an asynchronous context: `task::spawn_blocking` and `task::block_in_place`.

#### spawn_blocking

The `task::spawn_blocking` function is similar to the `task::spawn` function discussed in the previous section, but rather than spawning an non-blocking future on the Tokio runtime, it instead spawns a blocking function on a dedicated thread pool for blocking tasks. For example:

    use tokio::task;

    task::spawn_blocking(|| {
        // do some compute-heavy work or call synchronous code
    });

Just like `task::spawn`, `task::spawn_blocking` returns a `JoinHandle` which we can use to await the result of the blocking operation:

    let join = task::spawn_blocking(|| {
        // do some compute-heavy work or call synchronous code
        "blocking completed"
    });

    let result = join.await?;
    assert_eq!(result, "blocking completed");

#### block_in_place

When using the multi-threaded runtime, the `task::block_in_place` function is also available. Like `task::spawn_blocking`, this function allows running a blocking operation from an asynchronous context. Unlike `spawn_blocking`, however, `block_in_place` works by transitioning the current worker thread to a blocking thread, moving other tasks running on that thread to another worker thread. This can improve performance by avoiding context switches.

For example:

    use tokio::task;

    let result = task::block_in_place(|| {
        // do some compute-heavy work or call synchronous code
        "blocking completed"
    });

    assert_eq!(result, "blocking completed");

#### yield_now

In addition, this module provides a `task::yield_now` async function that is analogous to the standard library's `thread::yield_now`. Calling and `await`ing this function will cause the current task to yield to the Tokio runtime's scheduler, allowing other tasks to be scheduled. Eventually, the yielding task will be polled again, allowing it to execute. For example:

    use tokio::task;

    async {
        task::spawn(async {
            // ...
            println!("spawned task done!")
        });

        // Yield, allowing the newly-spawned task to execute first.
        task::yield_now().await;
        println!("main task done!");
    }

## Structs

JoinError | Task failed to execute to completion.
JoinHandle | An owned permission to join on a task (await its termination).
LocalKey | A key for task-local data.
LocalSet | A set of tasks which are executed on the same thread.

## Functions

block_in_place | Runs the provided blocking function on the current thread without blocking the executor.
spawn | Spawns a new asynchronous task, returning a `JoinHandle` for it.
spawn_blocking | Runs the provided closure on a thread where blocking is acceptable.
spawn_local | Spawns a `!Send` future on the local task set.
yield_now | Yields execution back to the Tokio runtime.