标签: rust-tokio

使用异步函数进行 Rust 文档测试 #[tokio-test]

似乎无法#[tokio-test]在 Rust 文档测试中用于测试异步函数?

现在,我必须编写一个异步主函数,并用它来标记它#[tokio-main]并调用test_fn().await它,以让一些异步函数在cargo test --doc.

是否还有其他更好的方法来允许文档测试像普通测试功能一样运行,例如使用#[tokio-test]?另外,如果标签#[tokio-test]可以在文档中显示,那就太好了,这样用户就可以复制文档并直接在项目中将其用作测试。(这可能可以像这样完成##[tokio-test]?)

rust rust-cargo rust-tokio

7
推荐指数
2
解决办法
6784
查看次数

Tokio 错误:“没有正在运行的反应器”,即使安装了 #[tokio::main] 和单个版本的 tokio

当运行这样的代码时:

use futures::executor;
...
pub fn store_temporary_password(email: &str, password: &str) -> Result<(), Box<dyn Error>> {
  let client = DynamoDbClient::new(Region::ApSoutheast2);
  ...
  let future = client.put_item(input);
  executor::block_on(future)?; <- crashes here
  Ok(())
}
Run Code Online (Sandbox Code Playgroud)

我收到错误:

thread '<unnamed>' panicked at 'there is no reactor running, must be called from the context of a Tokio 1.x runtime
Run Code Online (Sandbox Code Playgroud)

我的 main 具有 tokio 注释,因为它应该是:

#[tokio::main]
async fn main() {
  ...
Run Code Online (Sandbox Code Playgroud)

我的 Cargo.toml 看起来像:

[dependencies]
...
futures = { version="0", features=["executor"] }
tokio = "1"
Run Code Online (Sandbox Code Playgroud)

我的 cars.lock 显示我只有 futures …

rust rust-tokio

7
推荐指数
1
解决办法
7476
查看次数

由于 *mut u8,异步块创建的 Future 不是 `Send`

我能够继续实现我的异步 udp 服务器。但是,此错误出现两次,因为我的变量数据的类型*mut u8不是Send

error: future cannot be sent between threads safely
 help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `*mut u8`
note: captured value is not `Send`
Run Code Online (Sandbox Code Playgroud)

和代码(MRE):

use std::error::Error;
use std::time::Duration;
use std::env;
use tokio::net::UdpSocket;
use tokio::{sync::mpsc, task, time}; // 1.4.0
use std::alloc::{alloc, Layout};
use std::mem;
use std::mem::MaybeUninit;
use std::net::SocketAddr;

const UDP_HEADER: usize = 8;
const IP_HEADER: usize = 20;
const AG_HEADER: usize = 4;
const MAX_DATA_LENGTH: usize = (64 …
Run Code Online (Sandbox Code Playgroud)

rust debouncing rust-tokio

7
推荐指数
1
解决办法
1万
查看次数

tokio可以理解为类似于Javascript的事件循环或者像它一样使用吗?

我不确定它是否tokio类似于 Javascript 中的事件循环,也是一个非阻塞运行时,或者它是否可以用于以类似的方式工作。以我的理解,tokio是 Rust 中 future 的运行时。因此,它必须实现某种用户态线程或任务,这可以通过事件循环(至少部分)来调度新任务来实现。

我们来看下面的 Javascript 代码:

console.log('hello1');
setTimeout(() => console.log('hello2'), 0);
console.log('hello3');
setTimeout(() => console.log('hello4'), 0);
console.log('hello5');
Run Code Online (Sandbox Code Playgroud)

输出将是

hello1
hello3
hello5
hello2
hello4
Run Code Online (Sandbox Code Playgroud)

我怎样才能在东京做到这一点?tokio 总体上是这样工作的吗?我尝试了以下代码

async fn set_timeout(f: impl Fn(), ms: u64) {
    tokio::time::sleep(tokio::time::Duration::from_millis(ms)).await;
    f()
}

#[tokio::main]
async fn main() {
    println!("hello1");
    tokio::spawn(async {set_timeout(|| println!("hello2"), 0)}).await;
    println!("hello3");
    tokio::spawn(async {set_timeout(|| println!("hello4"), 0)}).await;
    println!("hello5");
}
Run Code Online (Sandbox Code Playgroud)

输出只是

hello1
hello3
hello5
Run Code Online (Sandbox Code Playgroud)

如果我将代码更改为

    println!("hello1");
    tokio::spawn(async {set_timeout(|| println!("hello2"), 0)}.await).await;
    println!("hello3");
    tokio::spawn(async {set_timeout(|| println!("hello4"), 0)}.await).await;
    println!("hello5");
Run Code Online (Sandbox Code Playgroud)

输出是

hello1
hello2 …
Run Code Online (Sandbox Code Playgroud)

rust async-await rust-tokio

7
推荐指数
1
解决办法
2788
查看次数

根据当前运行环境获取tokio运行时句柄的正确方法

根据当前运行环境获取 tokio 运行时句柄的惯用方法是什么?

  • 对于已经在 tokio 运行时运行的方法,我想使用Handle.try_current().unwrap()它来获取当前的方法。
  • 对于不在 tokio 中运行的方法,我可以创建一个新方法:Runtime::new().unwrap().handle()

但是,当我将代码编写为:

fn get_runtime_handle() -> Handle {
    match Handle::try_current() {
        Ok(h) => h,
        Err(_) => Runtime::new().unwrap().handle().clone(),
    }
}

async fn a_async() -> Result<()> {
    ....
}

fn a() -> Result<()> {
   let handle = get_runtime_handle();
   handle.block_one (async { a_async().await; })
}

fn main() -> Result<()> {
    a();

    Ok(())
}

Run Code Online (Sandbox Code Playgroud)

tokio::fs::read_dir在内部调用,代码崩溃Error: Custom { kind: Other, error: "background task failed" }

当我handle.block_onRuntime::new().unwrap().handle().block_onin …

rust rust-tokio

7
推荐指数
1
解决办法
4800
查看次数

如何将任务添加到在另一个线程上运行的 Tokio 事件循环?

我想在 Rocket 服务器旁边启动 Tokio 事件循环,然后稍后将事件添加到该循环中。我读过有没有办法在新线程上启动 tokio::Delay 以允许主循环继续?,但我仍然不清楚如何实现我的目标。

future rust rust-tokio

6
推荐指数
1
解决办法
4177
查看次数

是否可以在不消耗其输出的情况下检查未来是否已准备好?

Rust 中的 Future 可以在不阻塞的情况下进行轮询,以检查 future 是否准备好(并在此过程中做一些工作)。考虑到这一点,是否可以在不消耗其输出的情况下“检查”未来是否已准备好?

可能的情况

stdin如果有任何数据,将会被轮询,并对输入(playground)采取行动:

async fn read_input_if_available() {
    use tokio::io::AsyncReadExt;

    let mut stdin = tokio::io::stdin();

    // if !stdin.ready() {
    //    return;
    // }

    let mut input = String::new();
    let mut buffer = [0_u8; 1024];

    while let Ok(bytes) = stdin.read(&mut buffer).await {
        if let Ok(string) = std::str::from_utf8(&buffer[..bytes]) {
            input.push_str(string);
        }
    }

    // Take action on `input` here
}
Run Code Online (Sandbox Code Playgroud)

当代码命中 时await,直到标准输入上有内容为止,即使只是等待EOF.

我使用tokio::io::Stdin它是因为它对于一个独立的示例来说更简单,但问题是关于 Rust 期货的。

asynchronous rust rust-tokio

6
推荐指数
1
解决办法
4874
查看次数

如何处理 tokio::spawn 闭包需要“static”和“&amp;self”?

我无法理解如何编写封装在一个结构中的并发异步代码。

我不确定如何准确解释这个问题,所以我会尝试用一个例子来解释。

假设我有一个UdpServer结构。该结构有多个与其行为相关的方法(例如handle_datagram,,,deserialize_datagram等)
如果我想让代码并发,我将生成 tokio 任务,这需要提供给它的闭包是静态的,这意味着我无法&self从内部调用这个任务只要&self不是静态的,这意味着我不能调用self.serialize_datagram().

我理解这个问题(不能保证结构会比线程寿命更长),但看不到解决它的正确方法。我知道可以将函数移出 impl,但这对我来说看起来不是一个好的解决方案。
另外,即使我们暂时假设我可以将其视为&self静态,但出于某种原因,这段代码在我看来仍然不正确(我猜不够生锈)。
另一个“解决方案”是采取self: Arc<Self>而不是&self,但这感觉更糟。

所以我假设有一些我不知道的模式。有人可以向我解释一下我应该如何重构整个事情吗?

示例代码:

struct UdpServer {}
impl UdpServer {
    pub async fn run(&self) {
        let socket = UdpSocket::bind(self.addr).await.unwrap();
        loop {
            let mut buf: &mut [u8] = &mut [];
            let (_, _) = socket.recv_from(&mut buf).await.unwrap();

            // I spawn tokio task to enable concurrency
            tokio::spawn(async move {
                // But i can't use …
Run Code Online (Sandbox Code Playgroud)

rust rust-tokio

6
推荐指数
1
解决办法
7638
查看次数

Rust 无法与“x86_64-w64-mingw32-gcc”链接

我正在尝试使用getrust 向 url 发出请求,每次运行此项目时都会收到此错误,而我的其他 rust 项目工作正常。这是我的cargo.toml文件。

[package]
name = "api_req"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = { version = "1.0", features = ["derive"] }
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"]}
Run Code Online (Sandbox Code Playgroud)

这是我尝试构建/运行代码时得到的输出。

error: linking with `x86_64-w64-mingw32-gcc` failed: exit code: 1
  |
  = note: "x86_64-w64-mingw32-gcc" "-fno-use-linker-plugin" "-Wl,--dynamicbase" "-Wl,--disable-auto-image-base" "-m64" "-Wl,--high-entropy-va" "C:\\Users\\sahil\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\self-contained\\crt2.o" "C:\\Users\\sahil\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\rsbegin.o" "C:\\Users\\sahil\\CLionProjects\\coc-rs\\target\\debug\\deps\\coc_rs-6b97e9afad26cc80.1ax3t6bk8kjti15h.rcgu.o" …
Run Code Online (Sandbox Code Playgroud)

rust rust-cargo rust-tokio

6
推荐指数
1
解决办法
4105
查看次数

当将 Arc&lt;Mutex&gt; 传递到 tokio::spawn 时,“未来无法在线程之间安全地发送”

我使用 tokio 实现了 TCP 客户端。但是,我的代码无法编译,因为出现错误:

error: future cannot be sent between threads safely
   --> src/main.rs:81:9
    |
81  |         tokio::spawn(async move {
    |         ^^^^^^^^^^^^ future created by async block is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `std::sync::MutexGuard<'_, Option<tokio::net::TcpStream>>`
note: future is not `Send` as this value is used across an await
   --> src/main.rs:90:42
    |
82  |             match stream.lock().unwrap().as_mut() {
    |                   ---------------------- has type `std::sync::MutexGuard<'_, Option<tokio::net::TcpStream>>` which is not `Send`
... …
Run Code Online (Sandbox Code Playgroud)

rust rust-tokio

6
推荐指数
1
解决办法
2409
查看次数