gpt4 book ai didi

multithreading - 为什么 Condvar 不唤醒最后一个线程?

转载 作者:行者123 更新时间:2023-11-29 08:22:39 25 4
gpt4 key购买 nike

我在使用 Condvar 时遇到了意想不到的结果。我知道我不能相信我的 wait() 不会早起,但在我的情况下,似乎总是缺少我的唤醒之一。鉴于此示例代码:

use std::sync::{Arc, Mutex, Condvar};
use std::{
thread,
time
};

fn main() {
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pause = time::Duration::from_secs(1);

for id in 0..10 {
let pair2 = pair.clone();
thread::spawn(move|| {
let &(ref lock, ref cvar) = &*pair2;

let lock = lock.lock().unwrap();
let _ = cvar.wait(lock).unwrap();
println!("Thread {} done!", id);
});
}

// Wait for the thread to start up.
let &(ref _lock, ref cvar) = &*pair;

for _ in 0..10 {
thread::sleep(pause);
cvar.notify_one();
}
}

我只让前八个线程退出循环:

Thread 0 done!
Thread 1 done!
Thread 2 done!
Thread 3 done!
Thread 4 done!
Thread 5 done!
Thread 6 done!
Thread 7 done!
Thread 8 done!

如果我将第二个循环的计数增加到 11,它实际上会唤醒全部 9 个。

我已经仔细检查了the documentationwait()notify_one() 上,但这里的问题并不明显。

有什么想法吗?这是错误还是我做的不对?

最佳答案

您的主线程不会等待工作线程完成,并且根据 the documentation of std::thread::spawn :

[…] the child thread may outlive the parent (unless the parent thread is the main thread; the whole process is terminated when the main thread finishes).

(重点是我的)

因为您的程序在最后一个 notify_one 之后立即终止,工作线程可能会在打印值之前被杀死。

当你循环 11 次时,在第 10 次 notify_all 之后会休眠 1s,这意味着最新的工作线程可能会完成它的工作。

该问题的一个常见解决方案是收集 spawn 返回的 JoinHandle,并根据 sn99's answer 等待它们。 .

关于multithreading - 为什么 Condvar 不唤醒最后一个线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55464131/

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