。-6ren">
gpt4 book ai didi

rust - 为什么 `tokio::main` 报告错误 "cycle detected when processing"?

转载 作者:行者123 更新时间:2023-12-02 12:23:40 25 4
gpt4 key购买 nike

我正在使用 Tokio 和 async/.await创建一个 UDP 服务器,我可以在其中以异步方式接收和发送数据。

SendHalf我的 UDP 套接字在多个任务之间共享。为此,我使用 Arc<Mutex<SendHalf>> 。这就是为什么Arc<Mutex<_>>存在。

use tokio::net::UdpSocket;
use tokio::net::udp::SendHalf;
use tokio::sync::mpsc;
use std::sync::{Arc, Mutex};
use std::net::SocketAddr;

struct Packet {
sender: Arc<Mutex<SendHalf>>,
buf: [u8; 512],
addr: SocketAddr,
}

#[tokio::main]
async fn main() {
let server = UdpSocket::bind(("0.0.0.0", 44667)).await.unwrap();
let (mut server_rx, mut server_tx) = server.split();
let sender = Arc::new(Mutex::new(server_tx));
let (mut tx, mut rx) = mpsc::channel(100);

tokio::spawn(async move {
loop {
let mut buffer = [0; 512];
let (_, src) = server_rx.recv_from(&mut buffer).await.unwrap();
let packet = Packet {
sender: sender.clone(),
buf: buffer,
addr: src,
};
tx.send(packet).await;
}
});

while let Some(packet) = rx.recv().await {
tokio::spawn(async move {
let mut socket = packet.sender.lock().unwrap();
socket.send_to(&packet.buf, &packet.addr).await.unwrap();
});
}
}

这里还有一个Playground .

我遇到了一个我不明白的编译器错误:

error[E0391]: cycle detected when processing `main`
--> src/main.rs:13:1
|
13 | #[tokio::main]
| ^^^^^^^^^^^^^^
|
note: ...which requires processing `main::{{closure}}#0::{{closure}}#1`...
--> src/main.rs:34:33
|
34 | tokio::spawn(async move {
| _________________________________^
35 | | let mut socket = packet.sender.lock().unwrap();
36 | | socket.send_to(&packet.buf, &packet.addr).await.unwrap();
37 | | });
| |_________^
= note: ...which again requires processing `main`, completing the cycle
note: cycle used when processing `main::{{closure}}#0`
--> src/main.rs:13:1
|
13 | #[tokio::main]
| ^^^^^^^^^^^^^^

为什么我的代码会产生一个循环?为什么调用需要处理main

该错误的详细含义是什么?我想了解发生了什么事。

最佳答案

根据tokio文档,当涉及using !Send value from a task时:

Holding on to a !Send value across calls to .await will result in an unfriendly compile error message similar to:

[... some type ...] cannot be sent between threads safely

or:

error[E0391]: cycle detected when processing main

您正在目睹这个确切的错误。当你 lock a Mutex :

pub fn lock(&self) -> LockResult<MutexGuard<T>>

它返回 MutexGuard ,即 !Send:

impl<'_, T: ?Sized> !Send for MutexGuard<'_, T>
<小时/>

编译良好:

#[tokio::main]
async fn main() {
...

while let Some(packet) = rx.recv().await {
let mut socket = packet.sender.lock().unwrap();
socket.send_to(&packet.buf, &packet.addr).await.unwrap();
}
}

关于rust - 为什么 `tokio::main` 报告错误 "cycle detected when processing"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59280296/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com