标签: rust-async-std

为什么异步版本的 TCP 回显服务器使用的内存比同步版本多 50 倍?

我有一个使用标准库的简单 TCP 回显服务器:

use std::net::TcpListener;

fn main() {
    let listener = TcpListener::bind("localhost:4321").unwrap();
    loop {
        let (conn, _addr) = listener.accept().unwrap();
        std::io::copy(&mut &conn, &mut &conn).unwrap();
    }
}
Run Code Online (Sandbox Code Playgroud)

它使用大约 11 MB 的内存:

标准库

东京

如果我将其转换为使用 tokio:

tokio = { version = "0.2.22", features = ["full"] }
Run Code Online (Sandbox Code Playgroud)
tokio = { version = "0.2.22", features = ["full"] }
Run Code Online (Sandbox Code Playgroud)

它使用 607 MB 的内存:

东京

async_std

同样,使用 async_std:

async-std = "1.6.2"
Run Code Online (Sandbox Code Playgroud)
use tokio::net::TcpListener;

#[tokio::main]
async fn main() {
    let mut listener = TcpListener::bind("localhost:4321").await.unwrap();
    loop {
        let (mut conn, _addr) …
Run Code Online (Sandbox Code Playgroud)

rust rust-tokio rust-async-std

5
推荐指数
2
解决办法
1173
查看次数

如何创建未来的 Vec

我有这个功能:

async fn get_events(r: RequestBuilder) -> Result<Vec<RepoEvent>, reqwest::Error> {
    Ok(r.send().await?.json::<Vec<RepoEvent>>().await?)
}
Run Code Online (Sandbox Code Playgroud)

我想存储一个Vecfuture 并等待它们全部:

let mut events = vec![];
for i in 1..=x {
    let req: RequestBuilder = client.get(&format!("https://example.com/api?page={}", i));

    events.append(get_events(req));
}
try_join_all(events).await.unwrap();
Run Code Online (Sandbox Code Playgroud)

我得到一个E0308: expected mutable reference, found opaque type.

应该是什么类型events

我可以通过推断类型来解决问题:

let events = (1..=x).map(|i| {
    let req: RequestBuilder = client.get(&format!("https://example.com/api?page={}", i));

    get_events(req);
});
Run Code Online (Sandbox Code Playgroud)

但我真的很想知道如何将 future 存储在向量中。

rust rust-async-std

5
推荐指数
0
解决办法
1638
查看次数

我如何在不等待的情况下运行未来?(生锈)

我有一些异步函数

async fn get_player(name: String, i: Instant) -> Option<Player> {
// some code here that returns a player structs
}
Run Code Online (Sandbox Code Playgroud)

在我的主函数中,我想在循环中同时运行上述函数,该函数大约需要 1 秒才能完成,并且我需要运行它至少 50 次,因此我想让它同时运行该函数 50 次。在我的主函数中,我有一个lazy_static自定义Client结构,该结构不应创建多次。

主功能

#[tokio::main]
async fn main() {
    client.init().await;

    println!("start");
    for i in 0..10 {
        println!("{}", i);
        let now = Instant::now();

        tokio::spawn(async move  {
            client.get_player("jay".to_string(), now).await;
        });
    }
    loop {}
}
Run Code Online (Sandbox Code Playgroud)

我传递即时的原因是因为在我的 get_player 函数中我有一个 println!() 只打印执行时间。

上面的 main 方法每个函数调用大约需要 500ms,但是下面的代码只需要 100ms。

#[tokio::main]
async fn maain(){
    client.init().await;

    for i in 0..10 {
        let now …
Run Code Online (Sandbox Code Playgroud)

rust rust-tokio rust-async-std

5
推荐指数
1
解决办法
6688
查看次数

Rust 中的“一种类型比另一种更通用”错误,而类型相同

我有以下代码

use std::future::Future;
fn main() {
    handle(Test::my_func);
}

fn handle<Fut>(fun: for<'r> fn(&'r mut Test) -> Fut) -> bool
where
    Fut: Future<Output = ()>,
{
    true
}

struct Test {}

impl Test {
    pub async fn my_func<'r>(&'r mut self) -> () {
        ()
    }
}
Run Code Online (Sandbox Code Playgroud)

此外,您可以在Rust Playground上在线运行它。

出现以下错误:

error[E0308]: mismatched types
  --> src/main.rs:4:12
   |
4  |     handle(Test::my_func);
   |            ^^^^^^^^^^^^^ one type is more general than the other
...
17 |     pub async fn my_func<'r>(&'r mut self) -> () { …
Run Code Online (Sandbox Code Playgroud)

rust lifetime-scoping rust-async-std rust-lifetimes rust-futures

4
推荐指数
1
解决办法
118
查看次数

如何从未来的函数中实现流

为了理解流是如何工作的,我试图实现一个使用 random.org 的无限数生成器。我做的第一件事是实现一个版本,在该版本中我将调用一个名为 get_number 的异步函数,它将填充缓冲区并返回下一个可能的数字:


struct RandomGenerator {
    buffer: Vec<u8>,
    position: usize,
}

impl RandomGenerator {
    pub fn new() -> RandomGenerator {
        Self {
            buffer: Vec::new(),
            position: 0,
        }
    }

    pub async fn get_number(&mut self) -> u8 {
        self.fill_buffer().await;

        let value = self.buffer[self.position];
        self.position += 1;

        value
    }

    async fn fill_buffer(&mut self) {
        if self.buffer.is_empty() || self.is_buffer_depleted() {
            let new_numbers = self.fetch_numbers().await;
            drop(replace(&mut self.buffer, new_numbers));
            self.position = 0;
        }
    }

    fn is_buffer_depleted(&self) -> bool {
        self.buffer.len() >= self.position
    }

    async …
Run Code Online (Sandbox Code Playgroud)

rust rust-tokio rust-async-std

3
推荐指数
1
解决办法
2745
查看次数

为什么我不能使用 rust tonic 并行发送多个请求?

我实现了 tonic helloworld教程。然后我尝试更改客户端代码,以便我可以在等待任何请求之前发送多个请求。

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let num_requests = 10;
    let mut client = GreeterClient::connect("http://[::1]:50051").await?;

    let mut responses = Vec::with_capacity(num_requests);
    for _ in 0..num_requests {
        let request = tonic::Request::new(HelloRequest {
            name: "Tonic".into(),
        });

        responses.push(client.say_hello(request));
    }
    for resp in responses {
        assert!(resp.await.is_ok());
    }

    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

这会导致编译错误:

error[E0499]: cannot borrow `client` as mutable more than once at a time
  --> src/client.rs:19:24
   |
19 |         responses.push(client.say_hello(request));
   |                        ^^^^^^ mutable borrow starts here in previous iteration of …
Run Code Online (Sandbox Code Playgroud)

rust rust-tokio rust-async-std

2
推荐指数
1
解决办法
1559
查看次数

在同步代码中使用 async/await 是否有任何性能优势?

我试图了解何时使用异步以及何时可以提高性能。

\n

我知道它 \xe2\x80\x99s 在替换其他阻塞 IO 操作(如文件 IO、http 调用、数据库操作等)方面最强大,但我想知道除此之外是否有 \xe2\x80\x99s 任何点(在至少就性能而言)。

\n

一个具体的例子可能是大内存副本(移动大向量或以其他方式复制大量数据)。这是一个同步操作,就程序的其余部分而言可能需要一段时间。这个示例是否可以利用 async/await 在等待副本时执行其他操作,或者线程必须等待内存副本才能继续执行?

\n

如果不是这个直接的例子,也许另一个可以通过 async/await 改进的同步操作?

\n

rust async-await rust-async-std

0
推荐指数
1
解决办法
914
查看次数