[Concurrency] Lock: ์กฐ๊ฑด ๋ณ€์ˆ˜ (Condition Variable)

Condition Variable์€ ๋Œ€ํ‘œ์ ์ธ ๋™์‹œ์„ฑ primitive ๊ตฌํ˜„ ์ค‘ ํ•˜๋‚˜๋‹ค.

์Šค๋ ˆ๋“œ ๊ฐ„์— ๊ธฐ๋‹ค๋ฆฌ๊ฑฐ๋‚˜(wait) ์•Œ๋ ค์„œ ๊นจ์›Œ์ฃผ๋Š”(notify) ๋“ฑ ๋™์ ์ธ ์ƒํ˜ธ์ž‘์šฉ์— ์ตœ์ ํ™”๋œ ๋™๊ธฐํ™” ์ˆ˜๋‹จ์ด๋‹ค.
ํŠนํžˆ ์˜ค๋žซ๋™์•ˆ ๊ธฐ๋‹ค๋ฆฌ๋Š” ํ–‰์œ„์— ์ž˜ ์ตœ์ ํ™”๋˜์–ด์žˆ๊ณ , ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ ์Šค๋ ˆ๋“œ๋ฅผ ์ฐจ๋‹จํ•ด์„œ CPU ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ๋ชจํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ํŠน์ง•์ด๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ์–ธ์–ด์—์„œ ๊ธฐ๋ณธ ๋ชจ๋“ˆ๋กœ ์ œ๊ณตํ•œ๋‹ค.
C++์—์„œ๋Š” "condition_variable", Rust๋Š” "CondVar", Go๋Š” sync.Cond, Java๋Š” Condition์ด๋ž€ ์ด๋ฆ„์œผ๋กœ ๋“ค์–ด๊ฐ€์žˆ๋‹ค.

๋‹ค์Œ์€ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ ์ฝ”๋“œ๋‹ค.

go

rust
wait์„ ํ†ตํ•ด ์Šค๋ ˆ๋“œ๋ฅผ ์ฐจ๋‹จํ•œ ์ฑ„ ๊ธฐ๋‹ค๋ฆฌ๊ณ , notify๋ฅผ ํ†ตํ•ด ์ฐจ๋‹จ๋œ ์Šค๋ ˆ๋“œ๋ฅผ ๊นจ์šธ ์ˆ˜ ์žˆ๋‹ค.
๋ชจ๋“  ์Šค๋ ˆ๋“œ๋ฅผ ๊นจ์šฐ๋Š” notify_all๊ณผ ํ•œ๋†ˆ๋งŒ ๊นจ์šฐ๋Š” notify_one 2๊ฐ€์ง€๊ฐ€ ์ œ๊ณต๋œ๋‹ค.

๋‹ค๋ฅธ ๋™๊ธฐํ™” ์ˆ˜๋‹จ๊ณผ ์œ ๋… ๋‹ค๋ฅธ ๋ถ€๋ถ„์€, ๋‹จ๋…์œผ๋กœ ์“ฐ์ด๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ Mutex์™€ ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜์–ด์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
go๋Š” ์•„์˜ˆ CondVar์˜ ์ƒ์„ฑ์ž์— Mutex๋ฅผ ๋„ฃ๋Š” ์‹์œผ๋กœ ๋งŒ๋“ค์–ด์ ธ์žˆ๋‹ค.

๊ตฌํ˜„ ์ˆ˜์ค€์—์„œ๋„ mutex์— ๊ฐ•ํ•˜๊ฒŒ ์˜์กดํ•œ๋‹ค.
Rust์˜ ๊ฒฝ์šฐ์—๋Š” spin loop ์—†์ด futex syscall์„ ๊ณง์žฅ ๋‚ ๋ฆฌ๋Š” ํ˜•ํƒœ๋กœ ๊ตฌํ˜„์ด ๋œ๋‹ค.

futex ๊ธฐ๋ฐ˜์œผ๋กœ ์ฆ‰์‹œ wait์„ ๊ฑธ๊ณ 


notify๋ฅผ ๋ณด๋ฉด futex awake๋ฅผ ๋‚ ๋ฆฐ๋‹ค.




ํ™œ์šฉ ์‹œ์˜ ์ด์ 

๊ทธ๋ž˜์„œ ์ด๊ฑธ ์™œ, ์–ด๋–จ ๋•Œ ์“ฐ๋Š”๊ฑธ๊นŒ? ์ฒ˜์Œ ์ ‘ํ•œ๋‹ค๋ฉด ๊ฝค ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ์ˆ˜๋„ ์žˆ๋‹ค.

๊ธฐ์‹ค ์Šค๋ ˆ๋“œ safeํ•˜๊ฒŒ ๊ธฐ๋‹ค๋ฆฌ๋Š” ํ–‰์œ„ ์ž์ฒด๋Š” Mutex๋กœ๋„ ๋‹ฌ์„ฑ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ด๋‹ค.
Mutex์˜ lock๋„ ์‹ค์ œ๋กœ ๋Œ€๊ธฐ ์ƒํƒœ์— ๋น ์ง€๋ฉด ์Šค๋ ˆ๋“œ๋ฅผ ์ฐจ๋‹จํ•œ๋‹ค.
๋ฌผ๋ก  ๋ถˆํ•„์š”ํ•œ spin loop๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— CondVar๋ณด๋‹ค๋Š” ๋น„์šฉ์ด ๋น„์‹ธ๋‹ค.

CondVar๊ฐ€ ํ•„์š”ํ•ด์ง€๋Š” ์ง€์ ์€, ๊ณต์œ ๋˜๋Š” ๊ฐ’ ์ ‘๊ทผ๊ณผ ๋ณ„๊ฐœ๋กœ ์ฃผ์ฒด์ ์œผ๋กœ ๋Œ€๊ธฐ/์žฌ์‹œ์ž‘์„ ํ•ด์•ผ ํ•  ๋•Œ๋‹ค.

Mutex์˜ lock์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋Œ€๊ธฐ๋Š” ๋‹จ์ˆœํ•˜๊ฒŒ "ํ•˜๋‚˜ ๋นผ๊ณ  ์ „๋ถ€ ๋Œ€๊ธฐ"์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ ๋…ผ๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ๊นŒ๋‹ค๋กญ๊ณ  ๋น„ํšจ์œจ์ ์ด๋‹ค.




vs ์ฑ„๋„

condvar์™€ ์ง์ ‘์ ์œผ๋กœ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋Š” ๋Œ€์ƒ์€ ์ฑ„๋„์ผ ๊ฒƒ์ด๋‹ค.
https://blog.naver.com/sssang97/223131767231
์ฑ„๋„์€ condvar์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋นˆ๋ฒˆํ•œ wait/wake ํŒจํ„ด ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ๋™๊ธฐํ™” ์ˆ˜๋‹จ์ด๋‹ค.
receiver๋Š” ์ด๋ฒคํŠธ๊ฐ€ ์—†์œผ๋ฉด wait ์ƒํƒœ์— ๋น ์ง€๊ณ , sender๊ฐ€ ๊ฐ’๊ณผ ํ•จ๊ป˜ wake๋ฅผ ๋‚ ๋ฆฌ๋ฉด ๊นจ์–ด๋‚˜๋Š” ์‹์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

๋‹จ์ผ ์Šค๋ ˆ๋“œ๊ฐ€ wait์„ ํ•˜๊ณ  1๊ฐœ ์ด์ƒ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ notify๋ฅผ ํ•˜๋Š”(mpsc) ๊ฒฝ์šฐ์—๋Š” ์ฑ„๋„์ด ๋” ์ ํ•ฉํ•˜๊ณ  ๊น”๋”ํ•˜๋‹ค.

๊ฐœ์ธ์ ์œผ๋กœ๋Š” ์ฑ„๋„์„ ๋จผ์ € ๊ณ ๋ คํ•ด๋ณด๊ณ , receiver๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ๊ฐ€ ๋˜๋Š” ๋“ฑ ์ฑ„๋„์˜ ๊ธฐ๋Šฅ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๊ฒŒ ๋˜๋ฉด convar๋ฅผ ํ†ตํ•ด ์ œ์–ด๋ฅผ ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค.



์ฐธ์กฐ
https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html
https://medium.com/@abhisheksagar_59776/mutex-vs-condition-variables-e0a15b2226a4