rust 当锁定将被释放时,将锁定 Package 到范围中是否会发生变化?

5ktev3wc  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(88)

用密码

fn do_something_under_lock(some_bool_mutex: &Mutex<bool>) {
    do_something_before_lock();

    let some_bool = some_bool_mutex.lock().unwrap();
    do_something_with_some_bool(some_bool);

    do_something_after_lock();
}

字符串
锁是否只在do_something_after_lock();之后释放?(或者编译器可以证明我们不需要长锁时间并减少它?)
如果锁只在do_something_after_lock();之后释放,我们是否可以通过将lock() Package 到自己的作用域中来更早地释放锁,如

fn do_something_under_lock_in_scope(some_bool_mutex: &Mutex<bool>) {
    do_something_before_lock();

    {
        let some_bool = some_bool_mutex.lock().unwrap();
        do_something_with_some_bool(some_bool);
    }

    do_something_after_lock();
}


Package 到作用域是告诉编译器我们想要什么的最好方法吗?还是我们应该使用其他方法,比如drop或其他方法?

l5tcr1uw

l5tcr1uw1#

锁将在do_something_after_lock()之后释放。这被认为是可观察到的行为,因此不允许编译器更改它。
在作用域中 Package 锁和使用drop()都很好。我更喜欢drop()版本,但这是主观的。但是,有一点需要注意,在异步函数中,即使您drop()它,锁也被认为是活动的。(它将被释放,但编译器仍会将其类型视为生成器类型的一部分),因此如果锁不能跨.await点持有,(例如因为它不是Send),你必须使用一个块,drop()是不够的。例如,以下代码会出错:

async fn foo(mutex: &Mutex<i32>) {
    let _guard = mutex.lock().unwrap();
    drop(_guard);
    
    tokio::time::sleep(Duration::from_secs(1)).await;
}

tokio::spawn(foo(mutex));

字符串
你需要使用一个block:

async fn foo(mutex: &Mutex<i32>) {
    {
        let _guard = mutex.lock().unwrap();
    }
    
    tokio::time::sleep(Duration::from_secs(1)).await;
}

tokio::spawn(foo(mutex));


This is expected to improve in future Rust versions的数据。

相关问题