Paul C
Paul C

Reputation: 8497

Only a portion of multiple non-returning function calls run concurrently with async/await

I have a test case that attempts to run async methods concurrently. My code attempts to start. 50 of these, but when I run it, only about 12 print the statement at the beginning of the async method.

What do I need to do to get them all running concurrently?

use futures::executor;
use futures::future;
use async_std;

async fn _spin(i: u32) {
    println!("starting {}", i);
    loop {
        //do work
    }
}

fn main() {
    let mut futures = vec![];
    for i in 0..50 {
        futures.push(_spin(i));
    }
    let handles = futures.into_iter().map(async_std::task::spawn).collect::<Vec<_>>();
    let joined = future::join_all(handles);
    let _results = executor::block_on(joined);
}

output. Note the ones that get run are seemingly randomly picked.

starting 0
starting 7
starting 12
starting 2
starting 11
starting 16
starting 10
starting 17
starting 1
starting 15
starting 3
starting 13

Upvotes: 0

Views: 84

Answers (1)

Jmb
Jmb

Reputation: 23453

If you call a "blocking" function, ie. a function that does a lot of work without calling await, then you should use spawn_blocking instead of spawn so that the function will get a dedicated thread. Otherwise tasks are spawned depending on the executor. In async-std, the default executor is a thread pool with at most as many threads as logical cores. You can however spawn tasks on other executors, including thread pools with a different number of threads:

futures::executor::ThreadPool;
let pool = ThreadPool::builder()
    .pool_size (2)
    .create()
    .unwrap();
pool.spawn_ok (async { /* do work */ });
/* Wait for tasks to complete */

Upvotes: 1

Related Questions