pub struct Handle { /* private fields */ }
Expand description
Handle to the runtime.
The handle is internally reference-counted and can be freely cloned. A handle can be
obtained using the Runtime::handle
method.
Implementations
sourceimpl Handle
impl Handle
sourcepub fn enter<F, R>(&self, f: F) -> R where
F: FnOnce() -> R,
pub fn enter<F, R>(&self, f: F) -> R where
F: FnOnce() -> R,
Enter the runtime context. This allows you to construct types that must
have an executor available on creation such as Delay
or TcpStream
.
It will also allow you to call methods such as tokio::spawn
.
This function is also available as Runtime::enter
.
Example
use tokio::runtime::Runtime;
fn function_that_spawns(msg: String) {
// Had we not used `handle.enter` below, this would panic.
tokio::spawn(async move {
println!("{}", msg);
});
}
fn main() {
let rt = Runtime::new().unwrap();
let handle = rt.handle().clone();
let s = "Hello World!".to_string();
// By entering the context, we tie `tokio::spawn` to this executor.
handle.enter(|| function_that_spawns(s));
}
sourcepub fn current() -> Self
pub fn current() -> Self
Returns a Handle
view over the currently running Runtime
Panic
This will panic if called outside the context of a Tokio runtime. That means that you must
call this on one of the threads being run by the runtime. Calling this from within a
thread created by std::thread::spawn
(for example) will cause a panic.
Examples
This can be used to obtain the handle of the surrounding runtime from an async block or function running on that runtime.
use tokio::runtime::Handle;
// Inside an async block or function.
let handle = Handle::current();
handle.spawn(async {
println!("now running in the existing Runtime");
});
thread::spawn(move || {
// Notice that the handle is created outside of this thread and then moved in
handle.block_on(async { /* ... */ })
// This next line would cause a panic
// let handle2 = Handle::current();
});
sourcepub fn try_current() -> Result<Self, TryCurrentError>
pub fn try_current() -> Result<Self, TryCurrentError>
Returns a Handle view over the currently running Runtime
Returns an error if no Runtime has been started
Contrary to current
, this never panics
sourceimpl Handle
impl Handle
sourcepub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>ⓘNotable traits for JoinHandle<T>impl<T> Future for JoinHandle<T> type Output = Result<T, JoinError>;
where
F: Future + Send + 'static,
F::Output: Send + 'static,
pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>ⓘNotable traits for JoinHandle<T>impl<T> Future for JoinHandle<T> type Output = Result<T, JoinError>;
where
F: Future + Send + 'static,
F::Output: Send + 'static,
Spawns a future onto the Tokio runtime.
This spawns the given future onto the runtime’s executor, usually a thread pool. The thread pool is then responsible for polling the future until it completes.
See module level documentation for more details.
Examples
use tokio::runtime::Runtime;
// Create the runtime
let rt = Runtime::new().unwrap();
let handle = rt.handle();
// Spawn a future onto the runtime
handle.spawn(async {
println!("now running on a worker thread");
});
Panics
This function will not panic unless task execution is disabled on the
executor. This can only happen if the runtime was built using
Builder
without picking either basic_scheduler
or
threaded_scheduler
.
sourcepub fn block_on<F: Future>(&self, future: F) -> F::Output
pub fn block_on<F: Future>(&self, future: F) -> F::Output
Run a future to completion on the Tokio runtime from a synchronous context.
This runs the given future on the runtime, blocking until it is complete, and yielding its resolved result. Any tasks or timers which the future spawns internally will be executed on the runtime.
If the provided executor currently has no active core thread, this
function might hang until a core thread is added. This is not a
concern when using the threaded scheduler, as it always has active
core threads, but if you use the basic scheduler, some other
thread must currently be inside a call to Runtime::block_on
.
See also the module level documentation, which has a section on
scheduler types.
This method may not be called from an asynchronous context.
Panics
This function panics if the provided future panics, or if called within an asynchronous execution context.
Examples
Using block_on
with the threaded scheduler.
use tokio::runtime::Runtime;
use std::thread;
// Create the runtime.
//
// If the rt-threaded feature is enabled, this creates a threaded
// scheduler by default.
let rt = Runtime::new().unwrap();
let handle = rt.handle().clone();
// Use the runtime from another thread.
let th = thread::spawn(move || {
// Execute the future, blocking the current thread until completion.
//
// This example uses the threaded scheduler, so no concurrent call to
// `rt.block_on` is required.
handle.block_on(async {
println!("hello");
});
});
th.join().unwrap();
Using the basic scheduler requires a concurrent call to
Runtime::block_on
:
use tokio::runtime::Builder;
use tokio::sync::oneshot;
use std::thread;
// Create the runtime.
let mut rt = Builder::new()
.enable_all()
.basic_scheduler()
.build()
.unwrap();
let handle = rt.handle().clone();
// Signal main thread when task has finished.
let (send, recv) = oneshot::channel();
// Use the runtime from another thread.
let th = thread::spawn(move || {
// Execute the future, blocking the current thread until completion.
handle.block_on(async {
send.send("done").unwrap();
});
});
// The basic scheduler is used, so the thread above might hang if we
// didn't call block_on on the rt too.
rt.block_on(async {
assert_eq!(recv.await.unwrap(), "done");
});
sourceimpl Handle
impl Handle
sourcepub fn spawn_blocking<F, R>(&self, f: F) -> JoinHandle<R>ⓘNotable traits for JoinHandle<T>impl<T> Future for JoinHandle<T> type Output = Result<T, JoinError>;
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
pub fn spawn_blocking<F, R>(&self, f: F) -> JoinHandle<R>ⓘNotable traits for JoinHandle<T>impl<T> Future for JoinHandle<T> type Output = Result<T, JoinError>;
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
Runs the provided closure on a thread where blocking is acceptable.
In general, issuing a blocking call or performing a lot of compute in a future without yielding is not okay, as it may prevent the executor from driving other futures forward. This function runs the provided closure on a thread dedicated to blocking operations. See the CPU-bound tasks and blocking code section for more information.
Tokio will spawn more blocking threads when they are requested through
this function until the upper limit configured on the Builder
is
reached. This limit is very large by default, because spawn_blocking
is
often used for various kinds of IO operations that cannot be performed
asynchronously. When you run CPU-bound code using spawn_blocking
, you
should keep this large upper limit in mind; to run your CPU-bound
computations on only a few threads, you should use a separate thread
pool such as rayon rather than configuring the number of blocking
threads.
This function is intended for non-async operations that eventually
finish on their own. If you want to spawn an ordinary thread, you should
use thread::spawn
instead.
Closures spawned using spawn_blocking
cannot be cancelled. When you
shut down the executor, it will wait indefinitely for all blocking
operations to finish. You can use shutdown_timeout
to stop waiting
for them after a certain timeout. Be aware that this will still not
cancel the tasks — they are simply allowed to keep running after the
method returns.
Note that if you are using the basic scheduler, this function will still spawn additional threads for blocking operations. The basic scheduler’s single thread is only used for asynchronous code.
Examples
use tokio::runtime::Runtime;
// Create the runtime
let rt = Runtime::new().unwrap();
let handle = rt.handle();
let res = handle.spawn_blocking(move || {
// do some compute-heavy work or call synchronous code
"done computing"
}).await?;
assert_eq!(res, "done computing");
Trait Implementations
Auto Trait Implementations
impl !RefUnwindSafe for Handle
impl Send for Handle
impl Sync for Handle
impl Unpin for Handle
impl !UnwindSafe for Handle
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcepub fn borrow_mut(&mut self) -> &mut T
pub fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcepub fn to_owned(&self) -> T
pub fn to_owned(&self) -> T
Creates owned data from borrowed data, usually by cloning. Read more
sourcepub fn clone_into(&self, target: &mut T)
pub fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more