std::sync::Condvar
基本使用
cvar.notify_one();通知单个任务
cvar.wait(guard).unwrap();获取通知
发送
notify_one
只叫醒1个正在等待的线程
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
fn main() {
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
let t1 = thread::spawn(move || {
thread::sleep(std::time::Duration::from_secs(5));
let (lock, cvar) = &*pair2;
let mut guard = lock.lock().unwrap();
*guard = true;
// 通知cvar
cvar.notify_one();
});
let t2 = thread::spawn(move || {
let (lock, cvar) = &*pair;
let mut guard = lock.lock().unwrap();
// 检查条件
while !*guard {
println!("waiting...: {}", *guard);
// 等待通知, 释放锁
guard = cvar.wait(guard).unwrap();
}
print!("done")
});
t1.join().unwrap();
t2.join().unwrap();
}
waiting...: false
done%
多线程使用notify_one
随机挑一个线程唤醒(操作系统决定)
不建议这样写
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
use std::time::Duration;
fn main() {
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let mut v = Vec::new();
for i in 0..4 {
let pair_clone = Arc::clone(&pair);
let t1 = thread::spawn(move || {
println!("等待[{}]", i);
let (lock, cvar) = &*pair_clone;
let mut guard = lock.lock().unwrap();
let (new_guard, timeout_result) =
cvar.wait_timeout(guard, Duration::from_secs(5)).unwrap();
if timeout_result.timed_out() {
println!("等待超时[{}]", i)
} else {
println!("done[{}]", i)
}
});
v.push(t1);
}
let t2 = thread::spawn(move || {
thread::sleep(Duration::from_secs(2));
let (lock, cvar) = &*pair;
let mut guard = lock.lock().unwrap();
*guard = true;
cvar.notify_one();
});
t2.join().unwrap();
for vv in v {
vv.join().unwrap();
}
}
等待[3]
等待[2]
等待[1]
等待[0]
done[3]
等待超时[2]
等待超时[1]
等待超时[0]
notify_all
叫醒所有正在等待的线程
use std::time::Duration;
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
fn main() {
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let mut v = Vec::new();
// 多线程监听
for i in 0..4 {
let pair_clone = Arc::clone(&pair);
let t1 = thread::spawn(move || {
let (lock, cvar) = &*pair_clone;
let mut guard = lock.lock().unwrap();
// 检查条件Mutex内容
while !*guard {
println!("waiting[{}]...: {}", i, *guard);
// 1.等待通知, 释放Mutex锁
// 2.收到通知, 重新获取Mutex内容
guard = cvar.wait(guard).unwrap();
}
// 3.跳出循环todo
println!("done[{}]", i)
});
v.push(t1);
}
let t2 = thread::spawn(move || {
thread::sleep(Duration::from_secs(2));
let (lock, cvar) = &*pair;
let mut guard = lock.lock().unwrap();
*guard = true;
cvar.notify_all();
});
t2.join().unwrap();
for vv in v {
vv.join().unwrap();
}
}
waiting[0]...: false
waiting[2]...: false
waiting[1]...: false
waiting[3]...: false
done[1]
done[2]
done[3]
done[0]
等待
wait
无限期等待直到被通知
wait(guard)返回MutexGuard<T>
use std::time::Duration;
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
fn main() {
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair1 = Arc::clone(&pair);
let t1 = thread::spawn(move || {
let (lock, cvar) = &*pair;
let mut guard = lock.lock().unwrap();
// 检查条件Mutex内容
while !*guard {
println!("waiting...: {}", *guard);
// 1.等待通知, 释放Mutex锁
// 2.收到通知, 重新获取Mutex内容
guard = cvar.wait(guard).unwrap();
}
// 3.跳出循环todo
print!("done")
});
let t2 = thread::spawn(move || {
thread::sleep(Duration::from_secs(2));
let (lock, cvar) = &*pair1;
let mut guard = lock.lock().unwrap();
*guard = true;
cvar.notify_one();
});
t1.join().unwrap();
t2.join().unwrap();
}
waiting...: false
done%
wait_timeout
带超时时间的等待
wait_timeout(guard, timeout)返回(MutexGuard<T>, WaitTimeoutResult)
use std::time::Duration;
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
fn main() {
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair1 = Arc::clone(&pair);
let t1 = thread::spawn(move || {
let (lock, cvar) = &*pair;
let guard = lock.lock().unwrap();
// new_guard是MutexGuard
// timeout_result是WaitTimeoutResult
let (new_guard, timeout_result) = cvar.wait_timeout(guard, Duration::from_secs(1)).unwrap();
println!("new_guard: {}", *new_guard);
println!("timeout_result: {:?}", timeout_result);
println!("time_out: {}", timeout_result.timed_out());
});
let t2 = thread::spawn(move || {
thread::sleep(Duration::from_secs(2));
let (lock, cvar) = &*pair1;
let mut guard = lock.lock().unwrap();
*guard = true;
cvar.notify_one();
});
t1.join().unwrap();
t2.join().unwrap();
}
new_guard: false
timeout_result: WaitTimeoutResult(true)
time_out: true
wait_while
带条件的无限等待
wait_while(guard, condition)返回MutexGuard<T>
use std::time::{Duration, Instant, SystemTime};
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
fn main() {
let pair = Arc::new((Mutex::new(0), Condvar::new()));
let pair1 = Arc::clone(&pair);
let t1 = thread::spawn(move || {
let (lock, cvar) = &*pair;
let guard = lock.lock().unwrap();
// new_guard是MutexGuard
// pending是MutexGuard(guard)内部的值
let new_guard = cvar.wait_while(guard, |pending| {
println!("pending: {}", pending);
// 内部返回false时才结束等待
// 返回true时,会一直等待
*pending < 1
}).unwrap();
println!("new_guard: {}", *new_guard);
});
let t2 = thread::spawn(move || {
thread::sleep(Duration::from_secs(1));
let (lock, cvar) = &*pair1;
let mut guard = lock.lock().unwrap();
*guard += 1;
cvar.notify_one();
});
t1.join().unwrap();
t2.join().unwrap();
}
pending: 0
pending: 1
new_guard: 1
wait_timeout_while
带条件和超时的等待
打印两次pending原因,第一次获取到锁打印判断,第二次是因为超时,获取到锁打印判断
wait_timeout_while(guard, timeout, condition)返回(MutexGuard<T>, WaitTimeoutResult)
use std::time::{Duration, Instant, SystemTime};
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
fn main() {
let pair = Arc::new((Mutex::new(0), Condvar::new()));
let pair1 = Arc::clone(&pair);
let t1 = thread::spawn(move || {
let (lock, cvar) = &*pair;
let guard = lock.lock().unwrap();
// new_guard是MutexGuard
// timeout_result是WaitTimeoutResult
// pending是MutexGuard(guard)内部的值
let (new_guard, timeout_result) = cvar.wait_timeout_while(guard, Duration::from_secs(1), |pending| {
println!("pending[t1]: {}", pending);
// 内部返回false时才结束等待
// 返回true时,会一直等待
*pending < 1
}).unwrap();
println!("new_guard[t1]: {}", *new_guard);
println!("timeout_result: {}", timeout_result.timed_out());
});
let t2 = thread::spawn(move || {
thread::sleep(Duration::from_secs(10));
let (lock, cvar) = &*pair1;
let mut guard = lock.lock().unwrap();
*guard += 1;
cvar.notify_one();
});
t1.join().unwrap();
t2.join().unwrap();
}
pending[t1]: 0
pending[t1]: 0
new_guard[t1]: 0
timeout_result: true
错误
WaitTimeoutResult
WaitTimeoutResult.timed_out(): 返回是否超时bool

浙公网安备 33010602011771号