Asynchronous 在异步函数的匹配中获取死锁
我在以下示例中遇到了一个死锁:Asynchronous 在异步函数的匹配中获取死锁,asynchronous,rust,future,deadlock,Asynchronous,Rust,Future,Deadlock,我在以下示例中遇到了一个死锁: use tokio::net::TcpListener; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use futures::lock::Mutex; use std::sync::Arc; struct A{ } impl A { pub async fn do_something(&self) -> std::result::Result<(), ()>{
use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use futures::lock::Mutex;
use std::sync::Arc;
struct A{
}
impl A {
pub async fn do_something(&self) -> std::result::Result<(), ()>{
Err(())
}
}
async fn lock_and_use(a: Arc<Mutex<A>>) {
match a.clone().lock().await.do_something().await {
Ok(()) => {
},
Err(()) => {
//try again on error
println!("trying again");
a.clone().lock().await.do_something().await.unwrap();
}
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("begin");
let a = Arc::new(Mutex::new(A{}));
lock_and_use(a.clone()).await;
println!("end");
Ok(())
}
没有问题,lock()
将在创建的同一行中消亡。我认为这个原则对于match
也是一样的。如果您考虑匹配,它会锁定该值,调用dou\u something
,等待它,然后比较该值。确实,dou\u something
返回了一个捕获了自我的未来,但是当我们等待它时,它应该丢弃自我。为什么它仍然保存着self
?如何在不克隆结果的情况下解决此问题?是:
临时工为整个陈述而活,从不缩短
原因代码可能是:
{
匹配self.cache.read(){//Some(数据)
_=>没有,
}
}.地图(|数据|{
//使用“数据”-最好保持锁定
})
阅读更多细节
因此,您需要在匹配语句之外锁定:
让x=a.clone().lock().wait.do_something().wait;
匹配x{
Ok(())=>{}
错误(())=>{
a、 clone().lock().wait.do_something().wait.unwrap();
}
}
但这仍然会导致死锁:@Gatonito no它不会在Result::unwrap()上调用Err
value:()',src/main.rs:25:57“线程'main'恐慌”?你让我放松了10分钟xd
a.clone().lock().await.do_something().await;
a.clone().lock().await.do_something().await;