为什么Mutex中的计数器与计数器的增量不一致?

问题描述 投票:0回答:1

虽然我正在练习代码,但要了解如何在多个线程中锁定和解锁互斥锁。我使用for循环运行10个不同的线程,并启动了一个互斥锁计数器变量。 for循环的实际增量很好,但与互斥锁计数器不一致。

let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];

for _ in 0..10 {
    let counter = Arc::clone(&counter);
    println!("Result: {:?}", counter);
    let handle = thread::spawn(move || {
        let mut num = counter.lock().unwrap();
        *num += 1;
    });
    handles.push(handle);
}
for handle in handles {
    handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap());

输出在互斥锁计数器中显示了一些荒谬的结果,我需要知道为什么会发生这种情况?

Result: Mutex { data: 0 } 
Result: Mutex { data: 0 }
Result: Mutex { data: 1 }
Result: Mutex { data: 2 }
Result: Mutex { data: 3 }
Result: Mutex { data: 4 }
Result: Mutex { data: 5 }
Result: Mutex { data: 6 }
Result: Mutex { data: 6 }
Result: Mutex { data: 8 }
Result: 10
rust synchronization mutex automatic-ref-counting
1个回答
0
投票

您正在主线程中打印结果,该主线程与其他线程并行运行,因此无法提供确定的结果。如果您在互斥锁被锁定后在生成的线程中打印结果(以确保一次只有一个线程看到该值),您将获得更合理的结果:

let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];

for _ in 0..10 {
    let counter = Arc::clone(&counter);
    let handle = thread::spawn(move || {
        let mut num = counter.lock().unwrap();
        *num += 1;
        println!("Result: {:?}", num);
    });
    handles.push(handle);
}
for handle in handles {
    handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap());

输出:

Result: 1
Result: 2
Result: 3
Result: 4
Result: 5
Result: 6
Result: 7
Result: 8
Result: 9
Result: 10
Result: 10
© www.soinside.com 2019 - 2024. All rights reserved.