gpt4 book ai didi

multithreading - 线程::spawn中的RwLock不会释放锁

转载 作者:行者123 更新时间:2023-12-03 11:43:42 25 4
gpt4 key购买 nike

我不确定为什么它卡在my.rw.write();上。

如果取消注释sleep调用,它将正常工作。这意味着在执行了派生线程并释放了RwLock之后,写访问尝试仍在阻塞主线程。我认为理论上一定很好。我哪里错了?

use std::sync::Arc;
use std::sync::RwLock;
use std::{thread, time};

struct MySt {
num1: i64,
num2: i64,
rw: RwLock<Vec<i64>>,
}

fn main() {
let my = Arc::new(MySt {
num1: 32,
num2: 64,
rw: RwLock::new(vec![1, 2, 3]),
});
let my2 = my.clone();
let t = thread::spawn(move || {
let mut rw = my2.rw.write().unwrap();
rw[0] = 5;
println!("child thread {}, {}, {}, {}", my2.num1, my2.num2, rw[0], rw[1]);
});
//thread::sleep(time::Duration::from_millis(1000));
let mut rw = my.rw.write().unwrap();
rw[1] = 6;
println!("main thread {}, {}, {}, {}", my.num1, my.num2, rw[0], rw[1]);
t.join().unwrap();
}

最佳答案

the write access attempt is still blocking the main thread after the spawn thread has been executed and has released the RwLock



这是不正确的。添加基本​​的调试输出以区分它们,表明唯一运行的 printlnmain中的那个。

不能保证在生成子线程之后哪个线程将首先执行。但是,由于主线程已经在运行,因此它可能会继续运行。如果是这样,它将通过 RwLock锁定 rw并按住 锁定,直到函数结束。但是,在函数结束之前,主线程将阻塞等待子线程的加入。子线程无法完成,因为它必须先获取写锁。您已经创建了经典死锁。

要解决此问题,请使用 drop显式解锁锁,或添加范围以限制锁的生命周期:
fn main() {
let my = Arc::new(MySt {
num1: 32,
num2: 64,
rw: RwLock::new(vec![1, 2, 3]),
});
let my2 = my.clone();
let t = thread::spawn(move || {
let mut rw = my2.rw.write().unwrap();
rw[0] = 5;
println!("thread a {}, {}, {}, {}", my2.num1, my2.num2, rw[0], rw[1]);
});
//thread::sleep(time::Duration::from_millis(1000));
let mut rw = my.rw.write().unwrap();
rw[1] = 6;
println!("thread b {}, {}, {}, {}", my.num1, my.num2, rw[0], rw[1]);
drop(rw);
t.join().unwrap();
}

添加 sleep可能会导致子线程首先执行。然后它将获取锁定并退出,从而允许主线程继续进行。

也可以看看:
  • How to "unlock" an RwLock?
  • 关于multithreading - 线程::spawn中的RwLock不会释放锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59384448/

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