Rust: thread park unpark - grizlupo/_ GitHub Wiki
์ด๋ฆ์ผ๋ก๋ ์ง์ ๋๋ ๊ฒ์ฒ๋ผ park๋ฅผ ํ๋ฉด ์ค๋ ๋๋ ๋ฉ์ถ๋ค. park๋ ํจ์๋ค. ๊ทธ๋ฐ๋ฐ ์ธ์๊ฐ ์๋ค. ๋ฐ๋ผ์ ๋์์ด ๋ ์ค๋ ๋๋ฅผ ์ง์ ํ ์๊ฐ ์๋ค. ์ด ๋ง์ ํ์ฌ ์ค๋ ๋๊ฐ ๋ฉ์ถ๋ค๋ ๊ฒ์ผ ํ ๊ณ , ์ด๊ฑด ๋ค์ ์ค์ค๋ก๋ง ๋ฉ์ถ ์ ์๋ค๋ ๋ง์ด ๋๋ค.
๋ฐ๋ฉด์ unpark๋ ์ค๋ ๋์ ๋ฉ์๋๋ค. ๊ทธ๋ฌ๋ ์ค๋ ๋๋ฅผ ํน์ ํ ์ ์๋ค. ๋ฉ์ถฐ ์๋ ์ค๋ ๋ ์ค์ค๋ก๋ ์๋ฌด๊ฒ๋ ํ ์ ์์ ํ ๋๊น ๋ค๋ฅธ ์ค๋ ๋๊ฐ unpark์ ํด์ค์ผ ํ๋ฆฐ๋ค.
park ํจ์ ์ค๋ช ์์ ์ค๋ฆฐ ์์ ๋ฅผ ๋ณด๋ฉด
use std::thread;
use std::sync::{Arc, atomic::{Ordering, AtomicBool}};
use std::time::Duration;
let flag = Arc::new(AtomicBool::new(false));
let flag2 = Arc::clone(&flag);
let parked_thread = thread::spawn(move || {
// We want to wait until the flag is set. We *could* just spin, but using
// park/unpark is more efficient.
while !flag2.load(Ordering::Acquire) {
println!("Parking thread");
thread::park();
// We *could* get here spuriously, i.e., way before the 10ms below are over!
// But that is no problem, we are in a loop until the flag is set anyway.
println!("Thread unparked");
}
println!("Flag received");
});
// Let some time pass for the thread to be spawned.
thread::sleep(Duration::from_millis(10));
// Set the flag, and let the thread wake up.
// There is no race condition here, if `unpark`
// happens first, `park` will return immediately.
// Hence there is no risk of a deadlock.
flag.store(true, Ordering::Release);
println!("Unpark the thread");
parked_thread.thread().unpark();
parked_thread.join().unwrap();
๋ด์ฉ์ parked_thread๋ผ๋ ์ค๋ ๋๋ฅผ ๋ง๋ค๊ณ , ์ค์ค๋ก ๋ฉ์ถ๋ฉด ๋ฉ์ธ ์ค๋ ๋๊ฐ ์ด๋ฅผ ํ์ด์ฃผ๋ ๊ฒ์ด๋ค.
์ข ๋ ๋ฏ์ด ๋ณด๋ฉด
while !flag2.load(Ordering::Acquire) {
println!("Parking thread");
thread::park();
// We *could* get here spuriously, i.e., way before the 10ms below are over!
// But that is no problem, we are in a loop until the flag is set anyway.
println!("Thread unparked");
}
parked_thread๋ flag2๊ฐ ์ฐธ์ผ ๋๊น์ง thread::park();
๋ฅผ ๋ฐ๋ณตํ๋๋ก ๋์ด ์๋ค.
flag2๋ ๊ผด๋ ์ฐธ/๊ฑฐ์ง ํ์ธ์ด ๋ชฉ์ ์ด์ง๋ง,
๋ ์ค๋ ๋์์ ๊ณต์ ํ๋ ๊ฐ์ด๋ค ๋ณด๋ AtomicBool ํ์ด๋ผ ๊ฑฐ์ฐฝํ๋ค.
atomic ์ฐ์ฐ์ ์ฃผ์ด์ง Ordering์ ๋ํด์๋ ์น์ด๋จน๋ C++ - <15 - 3. C++ memory order ์ atomic ๊ฐ์ฒด> ์ด ์ค๋ช
์ด C++์ ๊ธฐ์ค์ผ๋ก ํ์ง๋ง ์ ๋์ด ์๋ค.
๋ฉ์ธ ์ค๋ ๋๋
flag.store(true, Ordering::Release);
println!("Unpark the thread");
parked_thread.thread().unpark();
flag๋ฅผ ์ฐธ์ผ๋ก ์ค๋ค.
flag๊ณผ flag2๋ Arc๋ก clone๋ ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ๊ฐ์ ๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ parked_thread.thread().unpark();
ํ๋ค.
parked_thread๋ ํ๋ฆด ๊ฒ์ด๊ณ , flag๋ฅผ ์ด๋ฏธ ์ฐธ์ผ๋ก ํ๊ธฐ ๋๋ฌธ์ while ๋ฌธ์ด ๋๋๋ฉด์ ์ค๋ ๋๋ ๋๋ ๊ฒ์ด๋ค.
์คํ์ํค๋ฉด
Parking thread
Unpark the thread
Thread unparked
Flag received
์ด๋ ๊ฒ ๋๋ค.
์์ ๋ flag๋ฅผ ์ฐธ์ผ๋ก ์ฃผ๊ณ , unpark๋ฅผ ํ์ง๋ง ๋ง์ฝ ๊ทธ๋ฅ unpack๋ง ํ๋ค๋ฉด parked_thread๋ ๋ค์ park๋๋ฉด์ ๋ฉ์ถ ๊ฒ์ด๋ค. flag๋ฅผ ์ฐธ์ผ๋ก ์ฃผ๊ธฐ ์ ๊น์ง๋ unpack๋ฅผ ํด๋ ๊ณ์ ๋ค์ park ๋ ๊ฒ์ด๋ค.