Expand description
A runtime for writing reliable network applications without compromising speed.
Tokio is an event-driven, non-blocking I/O platform for writing asynchronousapplications with the Rust programming language. At a high level, itprovides a few major components:
- Tools forworking with asynchronous tasks, includingsynchronization primitives and channels andtimeouts, sleeps, andintervals.
- APIs forperforming asynchronous I/O, includingTCP and UDP sockets,filesystem operations, andprocess andsignal management.
- Aruntime for executing asynchronous code, including a task scheduler,an I/O driver backed by the operating system’s event queue (
epoll
,kqueue
,IOCP
, etc…), and a high performance timer.
Guide level documentation is found on thewebsite.
§A Tour of Tokio
Tokio consists of a number of modules that provide a range of functionalityessential for implementing asynchronous applications in Rust. In thissection, we will take a brief tour of Tokio, summarizing the major APIs andtheir uses.
The easiest way to get started is to enable all features. Do this byenabling thefull
feature flag:
tokio = { version = "1", features = ["full"] }
§Authoring applications
Tokio is great for writing applications and most users in this case shouldn’tworry too much about what features they should pick. If you’re unsure, we suggestgoing withfull
to ensure that you don’t run into any road blocks while you’rebuilding your application.
§Example
This example shows the quickest way to get started with Tokio.
tokio = { version = "1", features = ["full"] }
§Authoring libraries
As a library author your goal should be to provide the lightest weight cratethat is based on Tokio. To achieve this you should ensure that you only enablethe features you need. This allows users to pick up your crate without havingto enable unnecessary features.
§Example
This example shows how you may want to import features for a library that justneeds totokio::spawn
and use aTcpStream
.
tokio = { version = "1", features = ["rt", "net"] }
§Working With Tasks
Asynchronous programs in Rust are based around lightweight, non-blockingunits of execution calledtasks. Thetokio::task
module providesimportant tools for working with tasks:
- The
spawn
function andJoinHandle
type, for scheduling a new taskon the Tokio runtime and awaiting the output of a spawned task, respectively, - Functions forrunning blocking operations in an asynchronoustask context.
Thetokio::task
module is present only when the “rt” feature flagis enabled.
Thetokio::sync
module contains synchronization primitives to use whenneeding to communicate or share data. These include:
- channels (
oneshot
,mpsc
,watch
, andbroadcast
), for sending valuesbetween tasks, - a non-blocking
Mutex
, for controlling access to a shared, mutablevalue, - an asynchronous
Barrier
type, for multiple tasks to synchronize beforebeginning a computation.
Thetokio::sync
module is present only when the “sync” feature flag isenabled.
Thetokio::time
module provides utilities for tracking time andscheduling work. This includes functions for settingtimeouts fortasks,sleeping work to run in the future, orrepeating an operation at aninterval.
In order to usetokio::time
, the “time” feature flag must be enabled.
Finally, Tokio provides aruntime for executing asynchronous tasks. Mostapplications can use the#[tokio::main]
macro to run their code on theTokio runtime. However, this macro provides only basic configuration options. Asan alternative, thetokio::runtime
module provides more powerful APIs for configuringand managing runtimes. You should use that module if the#[tokio::main]
macro doesn’tprovide the functionality you need.
Using the runtime requires the “rt” or “rt-multi-thread” feature flags, toenable the current-threadsingle-threaded scheduler and themulti-threadscheduler, respectively. See theruntime
moduledocumentation for details. In addition, the “macros” featureflag enables the#[tokio::main]
and#[tokio::test]
attributes.
§CPU-bound tasks and blocking code
Tokio is able to concurrently run many tasks on a few threads by repeatedlyswapping the currently running task on each thread. However, this kind ofswapping can only happen at.await
points, so code that spends a long timewithout reaching an.await
will prevent other tasks from running. Tocombat this, Tokio provides two kinds of threads: Core threads and blocking threads.
The core threads are where all asynchronous code runs, and Tokio will by defaultspawn one for each CPU core. You can use the environment variableTOKIO_WORKER_THREADS
to override the default value.
The blocking threads are spawned on demand, can be used to run blocking codethat would otherwise block other tasks from running and are kept alive whennot used for a certain amount of time which can be configured withthread_keep_alive
.Since it is not possible for Tokio to swap out blocking tasks, like itcan do with asynchronous code, the upper limit on the number of blockingthreads is very large. These limits can be configured on theBuilder
.
To spawn a blocking task, you should use thespawn_blocking
function.
#[tokio::main]async fnmain() {// This is running on a core thread.letblocking_task = tokio::task::spawn_blocking(|| {// This is running on a blocking thread. // Blocking here is ok.});// We can wait for the blocking task like this: // If the blocking task panics, the unwrap below will propagate the // panic.blocking_task.await.unwrap();}
If your code is CPU-bound and you wish to limit the number of threads usedto run it, you should use a separate thread pool dedicated to CPU bound tasks.For example, you could consider using therayon library for CPU-boundtasks. It is also possible to create an extra Tokio runtime dedicated toCPU-bound tasks, but if you do this, you should be careful that the extraruntime runsonly CPU-bound tasks, as IO-bound tasks on that runtimewill behave poorly.
Hint: If using rayon, you can use aoneshot
channel to send the result backto Tokio when the rayon task finishes.
§Asynchronous IO
As well as scheduling and running tasks, Tokio provides everything you needto perform input and output asynchronously.
Thetokio::io
module provides Tokio’s asynchronous core I/O primitives,theAsyncRead
,AsyncWrite
, andAsyncBufRead
traits. In addition,when the “io-util” feature flag is enabled, it also provides combinators andfunctions for working with these traits, forming as an asynchronouscounterpart tostd::io
.
Tokio also includes APIs for performing various kinds of I/O and interactingwith the operating system asynchronously. These include:
tokio::net
, which contains non-blocking versions ofTCP,UDP, andUnix Domain Sockets (enabled by the “net” feature flag),tokio::fs
, similar tostd::fs
but for performing filesystem I/Oasynchronously (enabled by the “fs” feature flag),tokio::signal
, for asynchronously handling Unix and Windows OS signals(enabled by the “signal” feature flag),tokio::process
, for spawning and managing child processes (enabled bythe “process” feature flag).
§Examples
A simple TCP echo server:
usetokio::net::TcpListener;usetokio::io::{AsyncReadExt, AsyncWriteExt};#[tokio::main]async fnmain() ->Result<(), Box<dynstd::error::Error>> {letlistener = TcpListener::bind("127.0.0.1:8080").await?;loop{let(mutsocket,_) = listener.accept().await?; tokio::spawn(async move{letmutbuf = [0;1024];// In a loop, read data from the socket and write the data back.loop{letn =matchsocket.read(&mutbuf).await{// socket closedOk(0) =>return,Ok(n) => n,Err(e) => {eprintln!("failed to read from socket; err = {:?}", e);return; } };// Write the data backif letErr(e) = socket.write_all(&buf[0..n]).await{eprintln!("failed to write to socket; err = {:?}", e);return; } } }); }}
§Feature flags
Tokio uses a set offeature flags to reduce the amount of compiled code. Itis possible to just enable certain features over others. By default, Tokiodoes not enable any features but allows one to enable a subset for their usecase. Below is a list of the available feature flags. You may also noticeabove each function, struct and trait there is listed one or more feature flagsthat are required for that item to be used. If you are new to Tokio it isrecommended that you use thefull
feature flag which will enable all public APIs.Beware though that this will pull in many extra dependencies that you may notneed.
full
: Enables all features listed below excepttest-util
andtracing
.rt
: Enablestokio::spawn
, the current-thread scheduler,and non-scheduler utilities.rt-multi-thread
: Enables the heavier, multi-threaded, work-stealing scheduler.io-util
: Enables the IO basedExt
traits.io-std
: EnableStdout
,Stdin
andStderr
types.net
: Enablestokio::net
types such asTcpStream
,UnixStream
andUdpSocket
, as well as (on Unix-like systems)AsyncFd
and (onFreeBSD)PollAio
.time
: Enablestokio::time
types and allows the schedulers to enablethe built in timer.process
: Enablestokio::process
types.macros
: Enables#[tokio::main]
and#[tokio::test]
macros.sync
: Enables alltokio::sync
types.signal
: Enables alltokio::signal
types.fs
: Enablestokio::fs
types.test-util
: Enables testing based infrastructure for the Tokio runtime.parking_lot
: As a potential optimization, use the_parking_lot_
crate’ssynchronization primitives internally. Also, thisdependency is necessary to construct some of our primitivesin aconst
context.MSRV
may increase according to the_parking_lot_
release in use.
Note:AsyncRead
andAsyncWrite
traits do not require any features and arealways available.
§Unstable features
Some feature flags are only available when specifying thetokio_unstable
flag:
tracing
: Enables tracing events.
Likewise, some parts of the API are only available with the same flag:
task::Builder
- Some methods on
task::JoinSet
runtime::RuntimeMetrics
runtime::Builder::on_task_spawn
runtime::Builder::on_task_terminate
runtime::Builder::unhandled_panic
runtime::TaskMeta
This flag enablesunstable features. The public API of these featuresmay break in 1.x releases. To enable these features, the--cfg tokio_unstable
argument must be passed torustc
when compiling. Thisserves to explicitly opt-in to features which may break semver conventions,since Cargodoes not yet directly support such opt-ins.
You can specify it in your project’s.cargo/config.toml
file:
[build]rustflags = ["--cfg", "tokio_unstable"]
[build]
section doesnot go in aCargo.toml
file. Instead it must be placed in the Cargo configfile.cargo/config.toml
.Alternatively, you can specify it with an environment variable:
## Many *nix shells:export RUSTFLAGS="--cfg tokio_unstable"cargo build
## Windows PowerShell:$Env:RUSTFLAGS="--cfg tokio_unstable"cargo build
§Supported platforms
Tokio currently guarantees support for the following platforms:
- Linux
- Windows
- Android (API level 21)
- macOS
- iOS
- FreeBSD
Tokio will continue to support these platforms in the future. However,future releases may change requirements such as the minimum required libcversion on Linux, the API level on Android, or the supported FreeBSDrelease.
Beyond the above platforms, Tokio is intended to work on all platformssupported by the mio crate. You can find a longer listin mio’sdocumentation. However, these additional platforms maybecome unsupported in the future.
Note that Wine is considered to be a different platform from Windows. Seemio’s documentation for more information on Wine support.
§WASM
support
Tokio has some limited support for theWASM
platform. Without thetokio_unstable
flag, the following features are supported:
sync
macros
io-util
rt
time
Enabling any other feature (includingfull
) will cause a compilationfailure.
Thetime
module will only work onWASM
platforms that have support fortimers (e.g. wasm32-wasi). The timing functions will panic if used on aWASM
platform that does not support timers.
Note also that if the runtime becomes indefinitely idle, it will panicimmediately instead of blocking forever. On platforms that don’t supporttime, this means that the runtime can never be idle in any way.
§UnstableWASM
support
Tokio also has unstable support for some additionalWASM
features. Thisrequires the use of thetokio_unstable
flag.
Using this flag enables the use oftokio::net
on the wasm32-wasi target.However, not all methods are available on the networking types asWASI
currently does not support the creation of new sockets from withinWASM
.Because of this, sockets must currently be created via theFromRawFd
trait.
Re-exports§
pub use task::spawn;
rt
Modules§
- doc
- Types which are documented locally in the Tokio crate, but does not actuallylive here.
- fs
fs
- Asynchronous file utilities.
- io
- Traits, helpers, and type definitions for asynchronous I/O functionality.
- net
- TCP/UDP/Unix bindings for
tokio
. - process
process
- An implementation of asynchronous process management for Tokio.
- runtime
rt
- The Tokio runtime.
- signal
signal
- Asynchronous signal handling for Tokio.
- stream
- Due to the
Stream
trait’s inclusion instd
landing later than Tokio’s 1.0release, most of the Tokio stream utilities have been moved into thetokio-stream
crate. - sync
sync
- Synchronization primitives for use in asynchronous contexts.
- task
- Asynchronous green-threads.
- time
time
- Utilities for tracking time.
Macros§
- join
macros
- Waits on multiple concurrent branches, returning whenall branchescomplete.
- pin
- Pins a value on the stack.
- select
macros
- Waits on multiple concurrent branches, returning when thefirst branchcompletes, cancelling the remaining branches.
- task_
local rt
- Declares a new task-local key of type
tokio::task::LocalKey
. - try_
join macros
- Waits on multiple concurrent branches, returning whenall branchescomplete with
Ok(_)
or on the firstErr(_)
.
Attribute Macros§
- main
rt
andmacros
- Marks async function to be executed by the selected runtime. This macrohelps set up a
Runtime
without requiring the user to useRuntime orBuilder directly. - test
rt
andmacros
- Marks async function to be executed by runtime, suitable to test environment.This macro helps set up a
Runtime
without requiring the user to useRuntime orBuilder directly.