首页 > 解决方案 > 如何强制 `async_std` 任务在 rust 的单个线程上运行?

问题描述

我是 rust 新手,第一次在 rust 中尝试异步。在此示例中,我正在运行递归斐波那契系列的 cpu 密集型运算,async-std无论我运行单个任务还是两个任务,它所花费的时间大致相同(约 7 秒)。

看起来任务正在由异步运行时在多个线程上执行。

有没有办法强制异步任务在同一个线程上运行?

use std::time;
use async_std::task;

fn main() {

    let start = time::Instant::now();

    let s1 = task::spawn(fib_async(46));
    let s2 = task::spawn(fib_async(46));

    task::block_on(s1);
    task::block_on(s2);
    let elap = time::Instant::now().duration_since(start);

    println!("time took for tasks to finish: {} seconds", elap.as_secs());

}


async fn fib_async(n: i32) -> i32 {
    fib(n)
}

fn fib(n: i32) -> i32 {
    if n == 0 || n == 1 {
        1
    } else {
        fib(n-1) + fib(n-2)
    }
}


标签: rust

解决方案


根据async_std::task你的文档不能。

这个模块类似于 std::thread,除了它使用异步任务代替线程。

所以它打算开始一个新线程,就像你用std::thread::spawn.

如果你想按顺序处理数据,你可以实现一个工人生产者模式:

use async_std::task;
use std::time;

#[async_std::main]
async fn main() {
    let (tx, rx) = flume::unbounded();

    let s = task::spawn(async move {
        for n in rx.into_iter() {
            println!("Calc fib of {}", n);
            let fib = fib_async(n).await;
            println!("{}", fib);
        }
    });

    let start = time::Instant::now();


    tx.send(40).unwrap();
    tx.send(40).unwrap();

    drop(tx);
    s.await;

    let elap = time::Instant::now().duration_since(start);
    println!("time took for tasks to finish: {} seconds", elap.as_secs());
}

async fn fib_async(n: i32) -> i32 {
    fib(n)
}

fn fib(n: i32) -> i32 {
    if n == 0 || n == 1 {
        1
    } else {
        fib(n - 1) + fib(n - 2)
    }
}

使用货物依赖项:

[dependencies]
async-std = { version = "1.5", features = ["attributes"] }
flume = "0.7"

推荐阅读