Experimenting with our new runtime 209 To run this example, follow these steps: 1. Replace everything below the imports in main. rs with the preceding code. 2. Run corofy. /src/main. rs. 3. Copy everything from main_corofied. rs to main. rs and delete main_corofied. rs. 4. Fix the fact that corofy doesn't know we changed our futures to take waker: &Waker as an argument. The easiest way is to simply run cargo check and let the compiler guide you to the places we need to change. Now, you can run the example and see that the tasks run concurrently, just as they did using join_all in Chapter 7. If you measured the time it takes to run the tasks, you' d find that it all takes around 4 seconds, which makes sense if you consider that you just spawned 5 futures, and ran them concurrently. The longest wait time for a single future was 4 seconds. Now, let's finish off this chapter with another interesting example. Running multiple futures concurrently and in parallel This time, we spawn multiple threads and give each thread its own Executor so that we can run the previous example simultaneously in parallel using the same Reactor for all Executor instances. We'll also make a small adjustment to the printout so that we don't get overwhelmed with data. Our new program will look like this: mod future; mod http; mod runtime; use crate::http::Http; use future::{Future, Poll State}; use runtime::{Executor, Waker}; use std::thread::Builder; fn main() { let mut executor = runtime::init(); let mut handles = vec![]; for i in 1..12 { let name = format!("exec-{i}"); let h = Builder::new(). name(name). spawn(move || { let mut executor = Executor::new(); executor. block_on(async_main()); }). unwrap(); handles. push(h);