如何在rust中使用随机数和时雄::time::sleep在异步函数中使用

bvuwiixz  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(110)

我有一个gRPC服务器方法,我想模拟一些工作,我有这个

async fn write(&self, request: Request<WriteRequest>)
                     -> Result<Response<WriteResponse>, Status> {
    let mut rng = rand::thread_rng();
    let random = rng.gen_range(1000..5000);
    // Sleep for the random duration
    sleep(Duration::from_millis(random)).await;
    return Ok(Response::new(WriteResponse { ... }));
}

但是代码对随机值不满意,我得到了错误

future cannot be sent between threads safely future created by async block is not `Send`

我知道我可以在函数中添加+ Send,但在本例中,我不能修改方法的签名,因为它是由gRPC编译器生成的接口
当我在作品中使用Duration内的硬编码值时。
如何调用随机数生成?或者我如何使用sleep来获得随机值?还有别的办法吗?

oxf4rvwz

oxf4rvwz1#

发生这种情况是因为rng超过了等待点。您可以通过将其封装在一个块中来解决这个问题,这可以确保它不会存储在async函数的状态机中。

let random_secs = {
    let mut rng = rand::thread_rng();
    rng.gen_range(1000..5000)
};

如果确实需要存储RNG,可以存储从thread_rng植入的普通PRNG(例如StdRng)。

use rand::{Rng, SeedableRng, rngs::StdRng};
    
let mut rng = {
    let rng = rand::thread_rng();
    StdRng::from_rng(rng).unwrap()
};
    
loop {
    let millis = rng.gen_range(1..10);
    tokio::time::sleep(std::time::Duration::from_millis(millis)).await;
    println!("{millis}");
}

相关问题