[Rust] threading: condvar
์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ค๋ณด๋ฉด, ์ด๊ฒ. ํญ์ ์ค๋ ๋๊ฐ ํํ์์ผ๋ก ๋๊ณ ์์ง ์์๋ ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
๊ทธ๋ฐ๋ฐ๋ ๊ดํ ์ค๋ ๋๋ฅผ ๋๋ฆฌ๋ฉด ๊ทธ๊ฒ๋ ๊ทธ๊ฒ๋๋ก ๋ฆฌ์์ค ๋ญ๋น๋ค.
๊ทธ๋์ ์ด๋ด๋, ํ์ํ ๋๋ง ์ค๋ ๋๋ฅผ ์คํ์ํค๊ณ ์ถ์๋ ์ฌ์ฉํ๋๊ฒ ๋ฐ๋ก ์กฐ๊ฑด ๋ณ์(condition variable)๋ผ๋ ๊ฒ์ด๋ค.
์ด๊ฑด Mutex ๋ฑ๊ณผ ํจ๊ป ์ฎ์ฌ์ ์ฐ์ด๋๋ฐ, ์ฎ์ฌ์๋ Mutex์ ๊ฐ์ด ์์ ๋๊ณ notify๊ฐ ๋ ๋ผ์ฌ ๋๊น์ง ๋ธ๋ญ์ ํ๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค.
์๋๋ ์ค๋ ๋๋ฅผ ์ ํ์ ์ผ๋ก ํ์ฑํํ๋ ๊ฒ์ ๋ํ ์์ ์ฝ๋๋ค.
use std::time::Duration;
fn main() {
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
// ์์ ๊ฐ์ false์
๋๋ค.
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
// mutex์ ๊ฐ์ด true์ธ ๋์์๋ง ๋ฃจํ๊ฐ ์คํ๋ฉ๋๋ค.
thread::spawn(move || {
let (lock, cvar) = &*pair2;
loop {
let mut available = lock.lock().unwrap();
println!("# ์ค๋ ๋ ์คํ์ค");
// false๋ผ๋ฉด wait์ผ๋ก ๋๊ธฐํฉ๋๋ค.
// main ์ค๋ ๋์์ true๋ก ๋ณ๊ฒฝํ๊ณ ์๋ฆผ์ ๋ณด๋ด๋ฉด true๊ฐ ๋์ด ์ฌํ์ฑํ๋ฉ๋๋ค.
if !*available {
available = cvar.wait(available).unwrap();
}
}
});
// ๋ฉ์ธ ์ค๋ ๋
let (lock, cvar) = &*pair;
println!("์์");
// ์ค๋ ๋ ํ์ฑํ
{
let mut available = lock.lock().unwrap();
*available = true;
cvar.notify_one();
}
std::thread::sleep(Duration::from_nanos(1));
// ์ค๋ ๋ ๋นํ์ฑํ
{
let mut available = lock.lock().unwrap();
*available = false;
}
println!("์ข
๋ฃ");
}
๊ทธ๋ผ ์ด๋ฐ์์ผ๋ก ์ค๋ ๋๊ฐ ์ ๊น ๋๋ค๊ฐ ๋ธ๋ญ๋ ๊ฒ์ด๋ค.


์ฐธ์กฐ
https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html
https://www.oreilly.com/library/view/rust-programming-by/9781788390637/b94b3983-429c-48ad-a6ef-7e15d664ca14.xhtml