0

I have many tasks to be executed in parallel, but I want to execute only a few tasks at a time. For example, I have 10 tasks and I want to execute only 2 tasks simultaneously.

Given this code using tokio.rs:

let mut runtime = Builder::new()
    .threaded_scheduler()
    .core_threads(2)
    .enable_all()
    .build()
    .unwrap();

runtime.block_on(async {
    let mut threads = Vec::new();
    for i in 0..10 {
        threads.push(tokio::spawn(async move {
            println!("Started thread {}", i);
            thread::sleep(Duration::from_millis(5000));
        }));
    }

    for i in threads {
        i.await.unwrap();
    }
})

Which prints this:

Started thread 0
Started thread 1
--wait 5 seconds--
Started thread 2
Started thread 3
--wait 5 seconds--
...

This is my desired behavior, but my function is async, so I need to .await it. When I .await it, it spins all tasks at once, even though I limited core_threads to 2.

Example code with .await using tokio.rs:

fn main() {
    let mut runtime = Builder::new()
        .threaded_scheduler()
        .core_threads(2)
        .enable_all()
        .build()
        .unwrap();

    runtime.block_on(async {
        let mut threads = Vec::new();
        for i in 0..10 {
            threads.push(tokio::spawn(async move {
                println!("Started thread {}", i);
                delay_for(Duration::from_millis(5000)).await;
            }));
        }

        for i in threads {
            i.await.unwrap();
        }
    });
}

but the output is now something like this:

Started thread 0
Started thread 1
Started thread 2
Started thread 3
....
--wait 5 seconds--

How can I achieve the desired behavior? Is there any Rust construct to "synchronize" async functions?

My desired behavior can be simulated in Golang using buffered channels.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
WutchZone
  • 154
  • 1
  • 3
  • 13
  • 1
    It looks like your question might be answered by the answers of [How can I perform parallel asynchronous HTTP GET requests with reqwest?](https://stackoverflow.com/q/51044467/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Jun 24 '20 at 14:30
  • 1
    You shouldn't rely on your first example also, please check: https://stackoverflow.com/questions/48735952/why-does-futureselect-choose-the-future-with-a-longer-sleep-period-first – Ömer Erden Jun 24 '20 at 14:34
  • 2
    [The duplicate applied to your case](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=caa8f8c9015eeb51e5d974127cdbd35d). – Shepmaster Jun 24 '20 at 14:35
  • 2
    See also [How do I synchronously return a value calculated in an asynchronous Future in stable Rust?](https://stackoverflow.com/q/52521201/155423). I also encourage you read up on the difference of *threads* and *tasks*. – Shepmaster Jun 24 '20 at 14:35

0 Answers0