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;