pub fn spawn_blocking<F, R>(f: F) ->JoinHandle<R>ⓘNotable traits forJoinHandle<T>impl<T>Future forJoinHandle<T> typeOutput =Result<T,JoinError>;where
F:FnOnce() -> R +Send + 'static,
R:Send + 'static, rt only.Runs the provided closure on a thread where blocking is acceptable.
In general, issuing a blocking call or performing a lot of compute in afuture without yielding is problematic, as it may prevent the executor fromdriving other futures forward. This function runs the provided closure on athread dedicated to blocking operations. See theCPU-bound tasks andblocking code section for more information.
Tokio will spawn more blocking threads when they are requested through thisfunction until the upper limit configured on theBuilder is reached.After reaching the upper limit, the tasks are put in a queue.The thread limit is very large by default, becausespawn_blocking is oftenused for various kinds of IO operations that cannot be performedasynchronously. When you run CPU-bound code usingspawn_blocking, youshould keep this large upper limit in mind. When running many CPU-boundcomputations, a semaphore or some other synchronization primitive should beused to limit the number of computation executed in parallel. SpecializedCPU-bound executors, such asrayon, may also be a good fit.
This function is intended for non-async operations that eventually finish ontheir own. If you want to spawn an ordinary thread, you should usethread::spawn instead.
Closures spawned usingspawn_blocking cannot be cancelled. When you shutdown the executor, it will wait indefinitely for all blocking operations tofinish. You can useshutdown_timeout to stop waiting for them after acertain timeout. Be aware that this will still not cancel the tasks — theyare simply allowed to keep running after the method returns.
Note that if you are using the single threaded runtime, this function willstill spawn additional threads for blocking operations. The basicscheduler’s single thread is only used for asynchronous code.
usetokio::task;letres=task::spawn_blocking(move|| {// do some compute-heavy work or call synchronous code"done computing"}).await?;assert_eq!(res,"done computing");