What the time it will be?

In the following code , make the assumption that

  1. the loading time of file1 and file2 are both 2 seconds
  2. ignore the other overhead

then what is the executing time of load?

  1. between 2 and 4
  2. exactly 4
#[tokio::main]
async fn load() {
  let x = tokio::fs::File::open("file1");
  let y = tokio::fs::File::open("file2");
  x.await;
  y.await;
}
1 Like

It will be exactly 4. The operations do not start until you .await them. To run them concurrently, use tokio::spawn, tokio::join! or some other concurrency primitive.

4 Likes

that is because Future is lazy? It seems this is not a hard rule . How about by adding an attribute macro like this

fn load() {
  let x = #[eager] tokio::fs::File::open("file1"); // work will start at this point
  let y = #[eager] tokio::fs::File::open("file2"); // work will start at this point
  x.get(); // pseudo code , will block until completed
  y.get();
}

Yes it's because futures are lazy. And regarding your proposed macro, that's what tokio::spawn does.

#[tokio::main]
async fn load() {
  let x = tokio::spawn(tokio::fs::File::open("file1"));
  let y = tokio::spawn(tokio::fs::File::open("file2"));
  x.await;
  y.await;
}
3 Likes

Yes. #[eager] do the same thing as spawn , but the macro has an advantage that it eliminate the use of await

You can't eliminate awaits and be sure that the async remains async. If your proposed get is blocking, then it will stop all tasks on the current thread, and we're back to the first step.

1 Like

Consider reading this:

The tokio::spawn method does not require that you .await its return value.

Yes. I know await is in fact desugared to a loop with a yield in it. I need put pieces together and think it as whole. thank you guys.

Not really. The real desugaring is a lot more complicated. Consider reading this.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.