mirror of https://github.com/rust-lang/async-book
Compare commits
14 Commits
9c300510c4
...
ed022fc51a
Author | SHA1 | Date |
---|---|---|
yuk1ty | ed022fc51a | |
Eric Holk | 1ef20c71ba | |
Eric Holk | cdb914881e | |
Bene | 04e8b6c093 | |
Bene | d4d750523a | |
Nereuxofficial | 87ac3cbdd3 | |
Bene | cc31e99108 | |
Bene | 330d3a4a85 | |
Bene | 3889ec843b | |
Bene | d9f4e062fa | |
Bene | 24861ba313 | |
Bene | 0f396afde7 | |
Bene | 6957e04fba | |
rouzbehsbz | 4ae6ecf928 |
|
@ -9,6 +9,7 @@ AsyncRead
|
|||
AsyncWrite
|
||||
AwaitingFutOne
|
||||
AwaitingFutTwo
|
||||
cancelling
|
||||
combinator
|
||||
combinators
|
||||
compat
|
||||
|
@ -37,6 +38,7 @@ interprocess
|
|||
IoBlocker
|
||||
IOCP
|
||||
IoObject
|
||||
JoinHandle
|
||||
kqueue
|
||||
localhost
|
||||
LocalExecutor
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "example_06_04_spawning"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3"
|
||||
|
||||
[dependencies.async-std]
|
||||
version = "1.12.0"
|
||||
features = ["attributes"]
|
|
@ -0,0 +1,46 @@
|
|||
#![cfg(test)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
// ANCHOR: example
|
||||
use async_std::{task, net::TcpListener, net::TcpStream};
|
||||
use futures::AsyncWriteExt;
|
||||
|
||||
async fn process_request(stream: &mut TcpStream) -> Result<(), std::io::Error>{
|
||||
stream.write_all(b"HTTP/1.1 200 OK\r\n\r\n").await?;
|
||||
stream.write_all(b"Hello World").await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn main() {
|
||||
let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();
|
||||
loop {
|
||||
// Accept a new connection
|
||||
let (mut stream, _) = listener.accept().await.unwrap();
|
||||
// Now process this request without blocking the main loop
|
||||
task::spawn(async move {process_request(&mut stream).await});
|
||||
}
|
||||
}
|
||||
// ANCHOR_END: example
|
||||
use std::time::Duration;
|
||||
async fn my_task(time: Duration) {
|
||||
println!("Hello from my_task with time {:?}", time);
|
||||
task::sleep(time).await;
|
||||
println!("Goodbye from my_task with time {:?}", time);
|
||||
}
|
||||
// ANCHOR: join_all
|
||||
use futures::future::join_all;
|
||||
async fn task_spawner(){
|
||||
let tasks = vec![
|
||||
task::spawn(my_task(Duration::from_secs(1))),
|
||||
task::spawn(my_task(Duration::from_secs(2))),
|
||||
task::spawn(my_task(Duration::from_secs(3))),
|
||||
];
|
||||
// If we do not await these tasks and the function finishes, they will be dropped
|
||||
join_all(tasks).await;
|
||||
}
|
||||
// ANCHOR_END: join_all
|
||||
|
||||
#[test]
|
||||
fn run_task_spawner() {
|
||||
futures::executor::block_on(task_spawner());
|
||||
}
|
|
@ -10,6 +10,7 @@ members = [
|
|||
"05_02_iteration_and_concurrency",
|
||||
"06_02_join",
|
||||
"06_03_select",
|
||||
"06_04_spawning",
|
||||
"07_05_recursion",
|
||||
"09_01_sync_tcp_server",
|
||||
"09_02_async_tcp_server",
|
||||
|
|
|
@ -645,7 +645,7 @@ execute_unpin_future(fut); // OK
|
|||
## Summary
|
||||
|
||||
1. If `T: Unpin` (which is the default), then `Pin<'a, T>` is entirely
|
||||
equivalent to `&'a mut T`. in other words: `Unpin` means it's OK for this type
|
||||
equivalent to `&'a mut T`. In other words: `Unpin` means it's OK for this type
|
||||
to be moved even when pinned, so `Pin` will have no effect on such a type.
|
||||
|
||||
2. Getting a `&mut T` to a pinned T requires unsafe if `T: !Unpin`.
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# `Spawning`
|
||||
|
||||
Spawning allows you to run a new asynchronous task in the background. This allows us to continue executing other code
|
||||
while it runs.
|
||||
|
||||
Say we have a web server that wants to accept connections without blocking the main thread.
|
||||
To achieve this, we can use the `async_std::task::spawn` function to create and run a new task that handles the
|
||||
connections. This function takes a future and returns a `JoinHandle`, which can be used to wait for the result of the
|
||||
task once it's completed.
|
||||
|
||||
```rust,edition2018
|
||||
{{#include ../../examples/06_04_spawning/src/lib.rs:example}}
|
||||
```
|
||||
|
||||
The `JoinHandle` returned by `spawn` implements the `Future` trait, so we can `.await` it to get the result of the task.
|
||||
This will block the current task until the spawned task completes. If the task is not awaited, your program will
|
||||
continue executing without waiting for the task, cancelling it if the function is completed before the task is finished.
|
||||
|
||||
```rust,edition2018
|
||||
{{#include ../../examples/06_04_spawning/src/lib.rs:join_all}}
|
||||
```
|
||||
|
||||
To communicate between the main task and the spawned task, we can use channels
|
||||
provided by the async runtime used.
|
|
@ -4,3 +4,4 @@ For resources in languages other than English.
|
|||
|
||||
- [Русский](https://doc.rust-lang.ru/async-book/)
|
||||
- [Français](https://jimskapt.github.io/async-book-fr/)
|
||||
- [فارسی](https://rouzbehsbz.github.io/rust-async-book/)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
- [Executing Multiple Futures at a Time](06_multiple_futures/01_chapter.md)
|
||||
- [`join!`](06_multiple_futures/02_join.md)
|
||||
- [`select!`](06_multiple_futures/03_select.md)
|
||||
- [TODO: Spawning]()
|
||||
- [Spawning](06_multiple_futures/04_spawning.md)
|
||||
- [TODO: Cancellation and Timeouts]()
|
||||
- [TODO: `FuturesUnordered`]()
|
||||
- [Workarounds to Know and Love](07_workarounds/01_chapter.md)
|
||||
|
|
Loading…
Reference in New Issue