Birden çok eşzamansız işlev aynı anda nasıl çalıştırılır ve sonuçları alınır?

Aug 18 2020

Tokio görevlerini denedim, ancak aynı anda birden fazla görevi yürütmek için çalışan örnekler yok. Bu kod ile ilgili yanlışlık nedir?

fn main() {
    block_on(speak());
}

async fn speak() {
    let hold = vec![say(), greet()];
    let results = join_all(hold).await;
}

async fn say() {
    println!("hello");
}

async fn greet() {
    println!("world");
}

işte derleyici çıktısı

error[E0308]: mismatched types
  --> sync\src\main.rs:14:27
   |
14 |     let hold = vec![say(),greet()];
   |                           ^^^^^^^ expected opaque type, found a different opaque type
...
23 | async fn greet(){
   |                 - the `Output` of this `async fn`'s found opaque type
   |
   = note:     expected type `impl core::future::future::Future` (opaque type at <sync\src\main.rs:19:15>)
           found opaque type `impl core::future::future::Future` (opaque type at <sync\src\main.rs:23:17>)
   = note: distinct uses of `impl Trait` result in different opaque types

Yanıtlar

6 Shepmaster Aug 18 2020 at 20:06

Sahip olduğunuz gibi iki gelecek için kullanın future::join

use futures::{executor, future}; // 0.3.5

async fn speak() {
    let (_s, _g) = future::join(say(), greet()).await;
}

Varyantları üç, dört ve beş girdi gelecekleri için vardır: join3, join4, join5.

Orada da try_join(ve try_join3, try_join4, try_join5gelecekteki bir döndüğünde için) Result.

Makro join, katılmak için statik sayıda vadeli işlem yapmanın başka bir yoludur.

Dinamik sayıda futures'i desteklemeniz gerekiyorsa, future::join_all(veya try_join_all) kullanabilirsiniz , ancak hepsinin bir türünün bir vektöre sahip olmanız gerekir. Bu, FutureExt::boxed(veya FutureExt::boxed_local) yoluyla en kolay olanıdır :

use futures::{executor, future, FutureExt}; // 0.3.5

async fn speak() {
    let futures = vec![say().boxed(), greet().boxed()];
    let _results = future::join_all(futures).await;
}

Bu kodun vadeli işlemleri aynı anda çalıştırabileceğini, ancak bunları paralel olarak çalıştırmayacağını unutmayın. Paralel yürütme için, bir tür görev başlatmanız gerekir.

Ayrıca bakınız:

  • Join_all'ın yaptığı gibi başarısızlık durumunda iptal etmeden bir vektördeki tüm futures'lara nasıl katılabilirim?
  • Sınırlı eşzamanlılıkla vadeli işlemlere katılın
  • Reqwest ile paralel zaman uyumsuz HTTP GET isteklerini nasıl gerçekleştirebilirim?
  • Nasıl heterojen bir nesne koleksiyonu oluşturabilirim?
  • Rust'ta zaman uyumsuz / beklemenin amacı nedir?
  • Eşzamanlılık ve paralellik arasındaki fark nedir?