Select
Select ์ฐ์ฐ์ ์ฌ๋ฌ future๋ค ๋ชจ๋์ ๋ํด์ ์ค๋น๋ ๋ ๊น์ง ๊ธฐ๋ค๋ฆฌ๋ค๊ฐ, ๊ทธ ์ค ์ด๋ค ํ future๊ฐ ์ต์ด๋ก ์ค๋น ์ํ๊ฐ ๋๋ฉด ํด๋น future์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฆฌํดํฉ๋๋ค. ์ด๊ฒ์ ์๋ฐ์คํฌ๋ฆฝํธ์์์ Promise.race
์ ๋น์ทํฉ๋๋ค. ํ์ด์ฌ์์๋ผ๋ฉด asyncio.wait(task_set, return_when=asyncio.FIRST_COMPLETED)
๊ฐ ํ๋ ๋์๊ณผ ๋น์ทํฉ๋๋ค.
Similar to a match statement, the body of select!
has a number of arms, each of the form pattern = future => statement
. When a future
is ready, its return value is destructured by the pattern
. The statement
is then run with the resulting variables. The statement
result becomes the result of the select!
macro.
use tokio::sync::mpsc::{self, Receiver}; use tokio::time::{sleep, Duration}; #[derive(Debug, PartialEq)] enum Animal { Cat { name: String }, Dog { name: String }, } async fn first_animal_to_finish_race( mut cat_rcv: Receiver<String>, mut dog_rcv: Receiver<String>, ) -> Option<Animal> { tokio::select! { cat_name = cat_rcv.recv() => Some(Animal::Cat { name: cat_name? }), dog_name = dog_rcv.recv() => Some(Animal::Dog { name: dog_name? }) } } #[tokio::main] async fn main() { let (cat_sender, cat_receiver) = mpsc::channel(32); let (dog_sender, dog_receiver) = mpsc::channel(32); tokio::spawn(async move { sleep(Duration::from_millis(500)).await; cat_sender.send(String::from("ํ ๋ฆญ์ค")).await.expect("๊ณ ์์ด๋ฅผ ๋ณด๋ด์ง ๋ชปํ์ต๋๋ค."); }); tokio::spawn(async move { sleep(Duration::from_millis(50)).await; dog_sender.send(String::from("๋ ์ค")).await.expect("๊ฐ๋ฅผ ๋ณด๋ด์ง ๋ชปํ์ต๋๋ค."); }); let winner = first_animal_to_finish_race(cat_receiver, dog_receiver) .await .expect("์ฐ์น์๋ฅผ ์์ ํ์ง ๋ชปํ์ต๋๋ค."); println!("์ฐ์น์: {winner:?}"); }
-
In this example, we have a race between a cat and a dog.
first_animal_to_finish_race
listens to both channels and will pick whichever arrives first. Since the dog takes 50ms, it wins against the cat that take 500ms. -
You can use
oneshot
channels in this example as the channels are supposed to receive only onesend
. -
Try adding a deadline to the race, demonstrating selecting different sorts of futures.
-
Note that
select!
drops unmatched branches, which cancels their futures. It is easiest to use when every execution ofselect!
creates new futures.- ๋์์ future ์์ฒด ๋์
&mut future
๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ ๋๋ค. ํ์ง๋ง ์ด๋ ๊ฒ ํ๋ฉด ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค(Pinning์ ๋ค๋ฃฐ ๋ ์์ธํ ์ค๋ช ํ ์์ ์).
- ๋์์ future ์์ฒด ๋์