CS

์šด์˜์ฒด์ œ ๊ณต๋ฃก์ฑ… : Ch6. Synchronization Tools | ๋™๊ธฐํ™” ๋„๊ตฌ๋“ค

Yunny52 2023. 3. 22. 23:49

๐Ÿ“Œ ๋“ค์–ด๊ฐ€๋ฉฐ

ํ˜‘๋ ฅ์  ํ”„๋กœ์„ธ์Šค cooperating process๋Š” ์‹œ์Šคํ…œ ๋‚ด์—์„œ ์‹คํ–‰ ์ค‘์ธ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์˜ ์‹คํ–‰์— ์˜ํ–ฅ์„ ์ฃผ๊ฑฐ๋‚˜ ์˜ํ–ฅ์„ ๋ฐ›๋Š” ํ”„๋กœ์„ธ์Šค์ด๋‹ค. ํ˜‘๋ ฅ์  ํ”„๋กœ์„ธ์Šค๋Š” ๋…ผ๋ฆฌ ์ฃผ์†Œ ๊ณต๊ฐ„(์ฆ‰, ์ฝ”๋“œ ๋ฐ ๋ฐ์ดํ„ฐ)์„ ์ง์ ‘ ๊ณต์œ ํ•˜๊ฑฐ๋‚˜ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ๋˜๋Š” ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ์„ ํ†ตํ•ด์„œ๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๊ณต์œ  ๋ฐ์ดํ„ฐ๋ฅผ ๋™์‹œ์— ์ ‘๊ทผํ•˜๋ฉด ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ๋ง์น  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฒˆ ๋‹จ์›์—์„œ๋Š” ๋…ผ๋ฆฌ ์ฃผ์†Œ ๊ณต๊ฐ„์„ ๊ณต์œ ํ•˜๋Š” ํ˜‘๋ ฅ์  ํ”„๋กœ์„ธ์Šค๊ฐ€ ์งˆ์„œ์žˆ๋Š” ์‹คํ–‰์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ๋Œ€ํ•ด ๋‹ค๋ฃจ์–ด๋ณด์ž.

 


๐Ÿ“š 6.1 ๋ฐฐ๊ฒฝ Background

 ํ”„๋กœ์„ธ์Šค๋Š” concurrentํ•˜๊ณ  parallelํ•˜๊ฒŒ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, CPU ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ํ”„๋กœ์„ธ์Šค ์‚ฌ์ด์—์„œ ๋น ๋ฅด๊ฒŒ ์˜ค๊ฐ€๋ฉฐ ๊ฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰ํ•˜๋ฉฐ ๊ฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๋ชจ๋“  ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ณ‘ํ–‰ ์‹คํ–‰์‹œํ‚จ๋‹ค. 

์ด๊ฒƒ์ด ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋Š”, ํ•œ ํ”„๋กœ์„ธ์Šค๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์Šค์ผ€์ค„ ๋˜๊ธฐ ์ „์— ์ผ๋ถ€๋ถ„๋งŒ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์‚ฌ์‹ค ํ”„๋กœ์„ธ์Šค๋Š” ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋  ๋•Œ ์–ด๋А ์ง€์ ์—์„œ๋‚˜ ์ธํ„ฐ๋ŸฝํŠธ ๋  ์ˆ˜ ์žˆ๊ณ , ์ฒ˜๋ฆฌ ์ฝ”์–ด๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ํ• ๋‹น๋  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์— ์†ํ•œ ๋‘ ๊ฐœ์˜ ๋ช…๋ น์–ด ํ๋ฆ„์ด ๋™์‹œ์— ๋‹ค๋ฅธ ์ฒ˜๋ฆฌ ์ฝ”์–ด์—์„œ ์‹คํ–‰๋  ์ˆ˜๋„ ์žˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ์˜ ๋™์‹œ ํ˜น์€ ๋ณ‘๋ ฌ ์‹คํ–‰์ด ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ณต์œ ํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ๋ฌด๊ฒฐ์„ฑ์— ์–ด๋–ค ์˜ํ–ฅ์„ ์ฃผ๊ฒŒ ๋ ๊นŒ?

 

๋™์‹œ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ ‘๊ทผํ•˜์—ฌ ์กฐ์ž‘ํ•˜๊ณ , ๊ทธ ์‹คํ–‰ ๊ฒฐ๊ณผ๊ฐ€ ์ ‘๊ทผ์ด ๋ฐœ์ƒํ•œ ํŠน์ • ์ˆœ์„œ์— ์˜์กดํ•˜๋Š” ์ƒํ™ฉ์„ ๊ฒฝ์Ÿ ์ƒํ™ฉ race condition์ด๋ผ๊ณ  ํ•œ๋‹ค. ๊ฒฝ์Ÿ ์ƒํ™ฉ์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด, ํ•œ์ˆœ๊ฐ„์— ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค๋งŒ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•˜๋„๋ก ๋ณด์žฅํ•ด์•ผ ํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ๋ณด์žฅ์„ ์œ„ํ•ด, ์–ด๋–ค ํ˜•ํƒœ๋กœ๋“  ํ”„๋กœ์„ธ์Šค๋“ค์ด ๋™๊ธฐํ™”๋˜์–ด์•ผ ํ•œ๋‹ค.

 


๐Ÿ“š 6.2 ์ž„๊ณ„๊ตฌ์—ญ ๋ฌธ์ œ The Critical-Section Problem

n๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๋กœ ์ด๋ฃจ์–ด์ง„ ์‹œ์Šคํ…œ์ด ์žˆ๋‹ค๊ณ  ํ•  ๋•Œ, ๊ฐ ํ”„๋กœ์„ธ์Šค๋Š” ์ž„๊ณ„๊ตฌ์—ญ critical section์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ์ฝ”๋“œ ๋ถ€๋ถ„์„ ํฌํ•จํ•˜๊ณ  ์žˆ๊ณ , ๊ทธ ์•ˆ์—์„œ๋Š” ์ ์–ด๋„ ํ•˜๋‚˜ ์ด์ƒ์˜ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์™€ ๊ณต์œ ํ•˜๋Š” ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๊ณ  ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž์‹ ์˜ ์ž„๊ณ„๊ตฌ์—ญ์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ๋™์•ˆ์—๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋“ค์€ ๊ทธ๋“ค์˜ ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์—†๋‹ค๋Š” ์ ์ด ์ค‘์š”ํ•˜๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•ด ๋‘ ํ”„๋กœ์„ธ์Šค๋Š” ๋™์‹œ์— ๊ทธ๋“ค์˜ ์ž„๊ณ„๊ตฌ์—ญ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๋‹ค. 

 

์ž„๊ณ„๊ตฌ์—ญ ๋ฌธ์ œ๋Š” ํ”„๋กœ์„ธ์Šค๋“ค์ด ๋ฐ์ดํ„ฐ๋ฅผ ํ˜‘๋ ฅ์ ์œผ๋กœ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•ด ์ž์‹ ๋“ค์˜ ํ™œ๋™์„ ๋™๊ธฐํ™”ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํ† ์ฝœ์„ ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ฐ ํ”„๋กœ์„ธ์Šค๋Š” ์ž์‹ ์˜ ์ž„๊ณ„๊ตฌ์—ญ์œผ๋กœ ์ง„์ž…ํ•˜๋ ค๋ฉด ์ง„์ž… ํ—ˆ๊ฐ€๋ฅผ ์š”์ฒญํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ์š”์ฒญ์„ ๊ตฌํ˜„ํ•˜๋Š” ์ฝ”๋“œ ๋ถ€๋ถ„์„ ์ง„์ž… ๊ตฌ์—ญ entry section์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ์ž„๊ณ„๊ตฌ์—ญ ๋’ค์—๋Š” ํ‡ด์ถœ ๊ตฌ์—ญ exit section์ด ๋”ฐ๋ผ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ์ฝ”๋“œ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„๋“ค์€ ์ด์นญํ•˜์—ฌ ๋‚˜๋จธ์ง€ ๊ตฌ์—ญ remainder section์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. 

์ž„๊ณ„๊ตฌ์—ญ ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์•ˆ์€ ๋‹ค์Œ์˜ ์„ธ๊ฐ€์ง€ ์š”๊ตฌ ์กฐ๊ฑด์„ ์ถฉ์กฑํ•ด์•ผ ํ•œ๋‹ค.

  1. ์ƒํ˜ธ ๋ฐฐ์ œ mutual exclusion
    • ๋งŒ์•ฝ ํ”„๋กœ์„ธ์Šค P_i๊ฐ€ ์ž์‹ ์˜ ์ž„๊ณ„๊ตฌ์—ญ์—์„œ ์‹คํ–‰๋œ๋‹ค๋ฉด, ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋“ค์€ ๊ทธ๋“ค ์ž์‹ ์˜ ์ž„๊ณ„๊ตฌ์—ญ์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์—†๋‹ค.
  2. ์ง„ํ–‰ progress
    • ๋งŒ์•ฝ ์•„๋ฌด ํ”„๋กœ์„ธ์Šค๋„ ์ž์‹ ์˜ ์ž„๊ณ„๊ตฌ์—ญ์„ ์‹คํ–‰ํ•˜๊ณ  ์žˆ์ง€ ์•Š๊ณ , ์–ด๋–ค ํ”„๋กœ์„ธ์Šค๋“ค์ด ์ž์‹ ์˜ ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ€๋ ค๊ณ  ํ•œ๋‹ค๋ฉด, ๋‚˜๋จธ์ง€ ๊ตฌ์—ญ์—์„œ ์‹คํ–‰ ์ค‘์ด์ง€ ์•Š์€ ํ”„๋กœ์„ธ์Šค๋“ค๋งŒ ๋‹ค์Œ์— ๋ˆ„๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์œผ๋กœ ์ง„์ž…ํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋ฉฐ, ์ด ์„ ํƒ์€ ๋ฌดํ•œ์ • ๋ฏธ๋ค„์งˆ ์ˆ˜ ์—†๋‹ค.
  3. ํ•œ์ •๋œ ๋Œ€๊ธฐ bounded waiting
    • ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž๊ธฐ์˜ ์ž„๊ณ„๊ตฌ์—ญ์— ์ง„์ž…ํ•˜๋ ค๋Š” ์š”์ฒญ์„ ํ•œ ํ›„๋ถ€ํ„ฐ ๊ทธ ์š”์ฒญ์ด ํ—ˆ์šฉ๋  ๋•Œ๊นŒ์ง€ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋“ค์ด ๊ทธ๋“ค ์ž์‹ ์˜ ์ž„๊ณ„๊ตฌ์—ญ์— ์ง„์ž…ํ•˜๋„๋ก ํ—ˆ์šฉ๋˜๋Š” ํšŸ์ˆ˜์— ํ•œ๊ณ„๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

 

์šด์˜์ฒด์ œ ๋‚ด์—์„œ ์ž„๊ณ„๊ตฌ์—ญ์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด ์„ ์ ํ˜• ์ปค๋„ preemptive kernel๊ณผ ๋น„์„ ์ ํ˜• ์ปค๋„ nonpreemptive kernel์˜ ๋‘ ๊ฐ€์ง€ ์ผ๋ฐ˜์ ์ธ ์ ‘๊ทผ๋ฒ•์ด ์‚ฌ์šฉ๋œ๋‹ค. ์„ ์ ํ˜• ์ปค๋„์€ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ปค๋„ ๋ชจ๋“œ์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ๋™์•ˆ ์„ ์ ๋˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•œ๋‹ค. ๋น„์„ ์ ํ˜• ์ปค๋„์€ ์ปค๋„ ๋ชจ๋“œ์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ํ”„๋กœ์„ธ์Šค์˜ ์„ ์ ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ณ  ์ปค๋„ ๋ชจ๋“œ ํ”„๋กœ์„ธ์Šค๋Š” ์ปค๋„์„ ๋น ์ ธ๋‚˜๊ฐˆ ๋•Œ๊นŒ์ง€ ๋˜๋Š” block ๋  ๋•Œ๊นŒ์ง€ ๋˜๋Š” ์ž๋ฐœ์ ์œผ๋กœ CPU์˜ ์ œ์–ด๋ฅผ ์–‘๋ณดํ•  ๋•Œ๊นŒ์ง€ ๊ณ„์† ์ˆ˜ํ–‰๋œ๋‹ค.

 

๋น„์„ ์ ํ˜• ์ปค๋„์€ ์ปค๋„ ์•ˆ์—์„œ ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋Š” ํ•˜๋‚˜ ๋ฐ–์— ์—†์œผ๋ฏ€๋กœ ์ปค๋„ ์ž๋ฃŒ๊ตฌ์กฐ์— ๋Œ€ํ•œ ๊ฒฝ์Ÿ ์กฐ๊ฑด์„ ์—ผ๋ คํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ทธ์— ๋น„ํ•ด ์„ ์ ํ˜• ์ปค๋„์€ ๊ฒฝ์Ÿ ์กฐ๊ฑด์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ์‹ ์ค‘ํ•˜๊ฒŒ ์„ค๊ณ„ํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ๋„ ์™œ ์„ ์ ์  ์ปค๋„์„ ๋” ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ผ๊นŒ? ์„ ์ ํ˜• ์ปค๋„์˜ ๊ฒฝ์šฐ, ์ปค๋„ ๋ชจ๋“œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋Œ€๊ธฐ ํ”„๋กœ์„ธ์Šค๋กœ ๋˜๊ธฐ๊นŒ์ง€ ์ƒ๋‹นํžˆ ๊ธด ๊ธฐ๊ฐ„ ๋™์•ˆ ์‹คํ–‰๋  ์œ„ํ—˜์ด ์ ๊ธฐ์— ์‘๋‹ต์ด ๋ฏผ์ฒฉํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์„ ์ ํ˜• ์ปค๋„์€ ์‹ค์‹œ๊ฐ„ ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ˜„์žฌ ์ปค๋„์—์„œ ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋ฅผ ์„ ์ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์‹œ๊ฐ„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๋” ์ ํ•ฉํ•˜๋‹ค.

 


๐Ÿ“š 6.3 ํ”ผํ„ฐ์Šจ์˜ ํ•ด๊ฒฐ์•ˆ Peterson's Solution

์ž„๊ณ„๊ตฌ์—ญ์— ๋Œ€ํ•œ ๊ณ ์ „์ ์ธ ์†Œํ”„ํŠธ์›จ์–ด ๊ธฐ๋ฐ˜ ํ•ด๊ฒฐ์ฑ…์ธ ํ”ผํ„ฐ์Šจ์˜ ํ•ด๊ฒฐ์•ˆ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

 

ํ”ผํ„ฐ์Šจ์˜ ํ•ด๊ฒฐ์•ˆ์€ ์ž„๊ณ„๊ตฌ์—ญ๊ณผ ๋‚˜๋จธ์ง€ ๊ตฌ์—ญ์„ ๋ฒˆ๊ฐˆ์•„ ๊ฐ€๋ฉฐ ์‹คํ–‰ํ•˜๋Š” ๋‘ ๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๋กœ ํ•œ์ •๋œ๋‹ค. ํ”„๋กœ์„ธ์Šค๋Š” P_0๊ณผ P_1๋กœ ๊ตฌ๋ถ„ํ•˜์ž. ํŽธ์˜์ƒ P_i๋ผ๊ณ  ํ‘œํ˜„ํ•  ๋•Œ, P_j๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  j๋Š” 1-i์™€ ๊ฐ™๋‹ค.

 

ํ”ผํ„ฐ์Šจ์˜ ํ•ด๊ฒฐ์•ˆ์€ ๋‘ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋‘ ๊ฐœ์˜ ๋ฐ์ดํ„ฐ ํ•ญ๋ชฉ์„ ๊ณต์œ ํ•ด์•ผ ํ•œ๋‹ค.

int turn;
boolean flag[2];

๋ณ€์ˆ˜ turn์€ ์ž„๊ณ„๊ตฌ์—ญ์œผ๋กœ ์ง„์ž…ํ•  ์ˆœ๋ฒˆ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. ๋งŒ์•ฝ turn == i์ด๋ฉด, ํ”„๋กœ์„ธ์Šค P_i๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋‹ค. 

flag ๋ฐฐ์—ด์€ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์œผ๋กœ ์ง„์ž…ํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. flag[i]๊ฐ€ ์ฐธ์ด๋ผ๋ฉด P_i๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์œผ๋กœ ์ง„์ž…ํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

 

while (true) {
    flag[i] = true;
    turn = j;
    while (flag[j] && turn == j)
    	;
        
        /* critical section */
        
	flag[i] = false;
    
    	/* remainder section */
 }

 

์ž„๊ณ„๊ตฌ์—ญ์œผ๋กœ ์ง„์ž…ํ•˜๊ธฐ ์œ„ํ•ด P_i๋Š” ๋จผ์ € flag[i]๋ฅผ ์ฐธ์œผ๋กœ ๋งŒ๋“ค๊ณ , turn์„ j๋กœ ์ง€์ •ํ•œ๋‹ค. ์ฆ‰, P_j๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์œผ๋กœ ์ง„์ž…ํ•˜๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๋ฉด ์ง„์ž… ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•œ๋‹ค. ๋งŒ์•ฝ ๋‘ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋™์‹œ์— ์ง„์ž…ํ•˜๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๋ฉด turn์€ ๊ฑฐ์˜ ๋™์‹œ์— i์™€ j๋กœ ์ง€์ •๋˜์ง€๋งŒ, ๋‘˜ ์ค‘ ์˜ค์ง ํ•œ ๋ฐฐ์ •๋งŒ์ด ์ง€์†๋œ๋‹ค. ๊ฒฐ๊ตญ turn์˜ ๊ถ๊ทน์ ์ธ ๊ฐ’์ด ๋‘˜ ์ค‘ ๋ˆ„๊ฐ€ ๋จผ์ € ์ž„๊ณ„๊ตฌ์—ญ์œผ๋กœ ์ง„์ž…ํ•  ๊ฒƒ์ธ๊ฐ€๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค.

 

ํ”ผํ„ฐ์Šจ์˜ ํ•ด๊ฒฐ์•ˆ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ฆ๋ช…ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‚ฌ์‹ค์„ ๋ณด์—ฌ์•ผ ํ•œ๋‹ค.

  1. ์ƒํ˜ธ ๋ฐฐ์ œ๊ฐ€ ์ œ๋Œ€๋กœ ์ง€์ผœ์ง„๋‹ค.
  2. ์ง„ํ–‰์— ๋Œ€ํ•œ ์š”๊ตฌ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•œ๋‹ค.
  3. ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ํ•œ์—†์ด ๊ธธ์–ด์ง€์ง€ ์•Š๋Š”๋‹ค.

1๋ฒˆ์„ ์ฆ๋ช…ํ•˜๋ ค๋ฉด, ๊ฐ P_i๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ€๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฐ˜๋“œ์‹œ flag[j] == false ์ด๋“ ์ง€ turn == i ์—ฌ์•ผ ํ•œ๋‹ค. ๋‘ ํ”„๋กœ์„ธ์Šค ๋ชจ๋‘ ์ž์‹ ์˜ ์ž„๊ณ„๊ตฌ์—ญ์— ์ง„์ž…ํ•˜๋ ค๊ณ  ํ•œ๋‹ค๋ฉด flag[i] == flag[j] == true๊ฐ€ ๋˜์ง€๋งŒ, turn ๋ณ€์ˆ˜์˜ ๊ฐ’์ด 0์ด๋ฉด์„œ 1์ผ ์ˆ˜๋Š” ์—†๊ธฐ์— P_i๊ณผ P_j๋Š” ๋™์‹œ์— while๋ฌธ์„ ํ†ต๊ณผํ•  ์ˆ˜ ์—†์„ ๊ฒƒ์ด๋‹ค. 

 

2๋ฒˆ๊ณผ 3๋ฒˆ์„ ์ฆ๋ช…ํ•˜๋ ค๋ฉด, P_i๊ฐ€ ์˜ค๋กœ์ง€ flag[j] == true์™€ turn == j์— ์˜ํ•ด while ๋ฃจํ”„ ์•ˆ์—์„œ ๊ณตํšŒ์ „ ํ•  ๋•Œ๋งŒ ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ€์ง€ ๋ชปํ•œ๋‹ค๋Š” ์ ์„ ๋“ค ์ˆ˜ ์žˆ๋‹ค.

P_j๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐˆ ์ค€๋น„๊ฐ€ ์•ˆ ๋˜์—ˆ์„ ๋•Œ๋Š” flag[j] == false ์ด๊ณ , P_i๋Š” ์ž„๊ณ„๊ตฌ์—ญ์— ์ง„์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค. P_j๊ฐ€ flag[j]๋ฅผ true๋กœ ์ง€์ •ํ•˜๊ณ  ์—ญ์‹œ ์ž์‹ ์˜ while๋ฌธ์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด ์ด๋•Œ turn์€ i์ด๊ฑฐ๋‚˜ j์ผ ๊ฒƒ์ด๋‹ค. turn == i ์ด๋ฉด P_i๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์— ์ง„์ž…ํ•˜๊ฒŒ ๋˜๊ณ , turn == j ์ด๋ฉด P_j๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์— ์ง„์ž…ํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ถ”ํ›„์— P_j๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์„ ๋น ์ ธ๋‚˜์˜ฌ ๋•Œ P_j๊ฐ€ flag[j]๋ฅผ false๋กœ ์žฌ์ง€์ •ํ•˜๊ณ  turn ๊ฐ’์„ i๋กœ ์ง€์ •ํ•˜์—ฌ P_i๊ฐ€ ์ง„์ž…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. P_i๊ฐ€ while๋ฌธ ์‹คํ–‰ ์ค‘์—” turn ๊ฐ’์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— P_j๊ฐ€ ์ง€๋‚œ๋ฒˆ์— ์ž„๊ณ„๊ตฌ์—ญ์— ์ง„์ž…ํ–ˆ๋‹ค๋ฉด P_i๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

 

ํ•˜์ง€๋งŒ ํ”ผํ„ฐ์Šจ์˜ ํ•ด๊ฒฐ์•ˆ์€ ์ตœ์‹  ์ปดํ“จํ„ฐ ์•„ํ‚คํ…์ฒ˜์—์„œ ์ž‘๋™ํ•œ๋‹ค๊ณ  ๋ณด์žฅ๋˜์ง„ ์•Š๋Š”๋‹ค. ์ฃผ๋œ ์ด์œ ๋Š” ์‹œ์Šคํ…œ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœ์„ธ์„œ ๋ฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ข…์†์„ฑ์ด ์—†๋Š” ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ ์ž‘์—…์„ ์žฌ์ •๋ ฌ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด, ๋‘ ์Šค๋ ˆ๋“œ ๊ฐ„์— ๊ณต์œ ๋˜๋Š” ๋‹ค์Œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณ ๋ คํ•˜์ž.

boolean flag = fasle;
int x = 0;

 

์—ฌ๊ธฐ์„œ ์Šค๋ ˆ๋“œ1์€ ๋‹ค์Œ ๋ช…๋ น๋ฌธ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

while(!flag)
	;
print x;

๊ทธ๋ฆฌ๊ณ  ์Šค๋ ˆ๋“œ2๋Š” ๋‹ค์Œ ๋ช…๋ น๋ฌธ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

x = 100;
flag = true;

 

์˜ˆ์ƒ๋˜๋Š” ๋™์ž‘์€ ์Šค๋ ˆ๋“œ1์ด ๋ณ€์ˆ˜ x์— ๋Œ€ํ•ด ๊ฐ’ 100์„ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ ๋ณ€์ˆ˜ flag์™€ x ์‚ฌ์ด์— ๋ฐ์ดํ„ฐ ์ข…์†์„ฑ์ด ์—†์œผ๋ฏ€๋กœ ํ”„๋กœ์„ธ์„œ๊ฐ€ ์Šค๋ ˆ๋“œ2์˜ ๋ช…๋ น์–ด๋ฅผ ์žฌ์ •๋ ฌํ•˜์—ฌ x=100์„ ๋ฐฐ์ •ํ•˜๊ธฐ ์ „์— flag๊ฐ€ true๋กœ ์ง€์ •๋  ์ˆ˜ ์žˆ๊ณ , ์ด ์ƒํ™ฉ์—์„œ ์Šค๋ ˆ๋“œ1์€ ๋ณ€์ˆ˜ x์— ๋Œ€ํ•ด 0์„ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค.

 


๐Ÿ“š 6.4 ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•œ ํ•˜๋“œ์›จ์–ด ์ง€์› Hardware Support for Synchronization

์†Œํ”„ํŠธ์›จ์–ด ๊ธฐ๋ฐ˜ ํ•ด๊ฒฐ์ฑ…์€ ์ตœ์‹  ์ปดํ“จํ„ฐ ์•„ํ‚คํ…์ฒ˜์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ์— ์ž„๊ณ„๊ตฌ์—ญ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์ง€์›์„ ์ œ๊ณตํ•˜๋Š” ์„ธ ๊ฐ€์ง€ ํ•˜๋“œ์›จ์–ด ๋ช…๋ น์–ด์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

 

6.4.1 ๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ Memory Barriers

6.3์ ˆ์—์„œ ๋ดค๋“ฏ์ด, ์‹œ์Šคํ…œ์€ ๋ช…๋ น์–ด์˜ ์ˆœ์„œ๋ฅผ ์žฌ์ •๋ ฌ ํ•  ์ˆ˜ ์žˆ๊ธฐ์— ๋ฐ์ดํ„ฐ์˜ ์‹ ๋ขฐ์„ฑ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ์ปดํ“จํ„ฐ ์•„ํ‚คํ…์ฒ˜๊ฐ€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—๊ฒŒ ์ œ๊ณตํ•  ๋ฉ”๋ชจ๋ฆฌ ๋ณด์žฅ์„ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐฉ์‹์„ ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ memory model์ด๋ผ๊ณ  ํ•˜๋Š”๋ฐ, ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ์€ ๋‘ ๊ฐ€์ง€๋กœ ๋ถ„๋ฅ˜๋œ๋‹ค.

  1. ๊ฐ•ํ•œ ์ˆœ์„œ strongly ordered :  ํ•œ ํ”„๋กœ์„ธ์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ณ€๊ฒฝ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค๋ฅธ ๋ชจ๋“  ํ”„๋กœ์„ธ์„œ์— ์ฆ‰์‹œ ๋ณด์ž„.
  2. ์•ฝํ•œ ์ˆœ์„œ weakly ordered : ํ•œ ํ”„๋กœ์„ธ์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ณ€๊ฒฝ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์„œ์— ์ฆ‰์‹œ ๋ณด์ด์ง€ ์•Š์Œ.

๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ์€ ํ”„๋กœ์„ธ์„œ ์œ ํ˜•์— ๋”ฐ๋ผ ๋‹ค๋ฅด๋ฏ€๋กœ ์ปค๋„ ๊ฐœ๋ฐœ์ž๋Š” ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ๋‹ค์ค‘ ์ฒ˜๋ฆฌ๊ธฐ์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๋ณ€๊ฒฝ์˜ ๊ฐ€์‹œ์„ฑ์— ๋Œ€ํ•œ ๊ฐ€์ •์„ ํ•  ์ˆ˜ ์—†๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ปดํ“จํ„ฐ ์•„ํ‚คํ…์ฒ˜๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋‹ค๋ฅธ ๋ชจ๋“  ํ”„๋กœ์„ธ์„œ๋กœ ์ „ํŒŒํ•˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ๋ช…๋ น์–ด๋ฅผ ๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ memory barriers ๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ํŽœ์Šค memory fences๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋  ๋•Œ, ์‹œ์Šคํ…œ์€ ๋ชจ๋“  ์ ์žฌ/์ €์žฅ ์—ฐ์‚ฐ์ด ๋‹ค์Œ ์ ์žฌ/์ €์žฅ ์—ฐ์‚ฐ์ด ์ˆ˜ํ–‰๋˜๊ธฐ ์ „์— ์™„๋ฃŒ๋˜๋„๋ก ํ•˜๊ธฐ์—, ๋ช…๋ น์ด ์žฌ์ •๋ ฌ๋˜๋”๋ผ๋„ ํ–ฅํ›„ ์ ์žฌ/์ €์žฅ ์ž‘์—…์ด ์ˆ˜ํ–‰๋˜๊ธฐ ์ „์— ์ €์žฅ ์ž‘์—…์ด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์™„๋ฃŒ๋˜์–ด ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์„œ์—๊ฒŒ๋„ ์ฆ‰์‹œ ๋ฐ˜์˜์ด ๋˜๋„๋ก ํ•œ๋‹ค.

 

๋ช…๋ น์–ด๋ฅผ ์žฌ์ •๋ ฌํ•˜์—ฌ ์ž˜๋ชป๋œ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์—ˆ๋˜ ๋ฌธ์ œ๋กœ ๋Œ์•„๊ฐ€๋ณด์ž.

๊ทธ๋ฆฌ๊ณ  ์—ฌ๊ธฐ์— ์˜ˆ์ƒ๋˜๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๋„๋ก ๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ์„ ์‚ฌ์šฉํ•ด๋ณด์ž.

 

์Šค๋ ˆ๋“œ1์— ๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ ์—ฐ์‚ฐ์„ ์ถ”๊ฐ€ํ•˜๋ฉด

while(!flag)
	memory_barrier();
print x;

flag ๊ฐ’์ด x ๊ฐ’๋ณด๋‹ค ๋จผ์ € ์ ์žฌ๋˜๋„๋ก ๋ณด์žฅํ•œ๋‹ค.

 

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์Šค๋ ˆ๋“œ2์—๋„ ๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ ์—ฐ์‚ฐ์„ ์ถ”๊ฐ€ํ•˜๋ฉด

x = 100;
memory_barrier();
flag = true;

flag์— ๋ฐฐ์ •ํ•˜๊ธฐ ์ „์— x์— ๋Œ€ํ•œ ๋ฐฐ์ •์ด ๋จผ์ € ์‹คํ–‰๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ์€ ๋งค์šฐ ๋‚ฎ์€ ์ˆ˜์ค€์˜ ์—ฐ์‚ฐ์œผ๋กœ ๊ฐ„์ฃผํ•˜๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ ์ƒํ˜ธ ๋ฐฐ์ œ๋ฅผ ๋ณด์žฅํ•˜๋Š” ํŠน์ˆ˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ์ปค๋„ ๊ฐœ๋ฐœ์ž๋งŒ ์‚ฌ์šฉํ•œ๋‹ค.

 

 

6.4.2 ํ•˜๋“œ์›จ์–ด ๋ช…๋ น์–ด Hardware Instructions

๋Œ€๋ถ€๋ถ„์˜ ํ˜„๋Œ€ ์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ์—์„œ๋Š” ์›์ž์ ์œผ๋กœ atomically ์›Œ๋“œ์˜ ๋‚ด์šฉ๋ฌผ์„ ํ…Œ์ŠคํŠธํ•˜๊ณ  ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ๋‘ ์›Œ๋“œ์˜ ๋‚ด์šฉ์„ ๊ตํ™˜ swapํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ํŠน์ˆ˜ํ•œ ํ•˜๋“œ์›จ์–ด ๋ช…๋ น์–ด๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์ด ํŠน์ˆ˜ํ•œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž„๊ณ„๊ตฌ์—ญ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. test_and_set()๊ณผ compare_and_swap() ๋ช…๋ น์–ด๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์‚ดํŽด๋ณด์ž.

 

test_and_set() ๋ช…๋ น์–ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

boolean test_and_set(boolean *target) {
    boolean rv = *target;
    *target = true;
    
    return rv;
}

์ค‘์š”ํ•œ ํŠน์ง•์€ ์ด ๋ช…๋ น์–ด๊ฐ€ ์›์ž์ ์œผ๋กœ ์‹คํ–‰๋˜๊ธฐ์— ๋งŒ์•ฝ ๋‘ test_and_set() ๋ช…๋ น์–ด๊ฐ€ (์„œ๋กœ ๋‹ค๋ฅธ ์ฝ”์–ด์—์„œ) ๋™์‹œ์— ์‹คํ–‰๋˜๋”๋ผ๋„ ์ž„์˜์˜ ์ˆœ์„œ๋กœ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰๋  ๊ฒƒ์ด๋‹ค. ๋งŒ์•ฝ ๊ธฐ๊ณ„๊ฐ€ test_and_set() ๋ช…๋ น์„ ์ง€์›ํ•œ๋‹ค๋ฉด, false๋กœ ์ดˆ๊ธฐํ™”๋˜๋Š” lock์ด๋ผ๋Š” boolean ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜์—ฌ ์ƒํ˜ธ ๋ฐฐ์ œ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ”„๋กœ์„ธ์Šค P_i์˜ ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์„ ๊ฒƒ์ด๋‹ค.

do {
    while (test_and_set(&lock))
    	; /* do nothing */
        
    /* critical section */
        
    lock = false;
        
    /* remainder section */
} while (true);

 

compare_and_swap() ๋ช…๋ น์–ด(CAS)๋Š” test_and_set() ๋ช…๋ น์–ด์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‘ ๊ฐœ์˜ ์›Œ๋“œ์— ๋Œ€ํ•ด ์›์ž์ ์ธ ์—ฐ์‚ฐ์„ ํ•˜์ง€๋งŒ ๋‘ ์›Œ๋“œ์˜ ๋‚ด์šฉ ๊ตํ™˜ swap์— ๊ธฐ๋ฐ˜์„ ๋‘” ๋‹ค๋ฅธ ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค. CAS ๋ช…๋ น์–ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋œ ์„ธ ๊ฐ€์ง€ ์—ฐ์‚ฐ์ž๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค.

int compare_and_swap(int *value, int expected, int new_value) {
    int temp = *value;
    
    if (*value == expected)
    	*value = new_value;
    
    return temp;
 }

ํ”ผ์—ฐ์‚ฐ์ž value๋Š” ์˜ค์ง (*value == expected) ์ˆ˜์‹์ด ์ฐธ์ผ ๋•Œ๋งŒ new_value๋กœ ์ง€์ •๋œ๋‹ค. ์ค‘์š”ํ•œ ๊ฒƒ์€ ๋ช…๋ น์ด ์›์ž์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฏ€๋กœ ๋‘ CAS๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ์ฝ”์–ด์—์„œ ๋™์‹œ์— ์‹คํ–‰๋˜๋ฉด ์ž„์˜์˜ ์ˆœ์„œ๋กœ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

 

ํ”„๋กœ์„ธ์Šค P_i์— ๋Œ€ํ•ด CAS๋ฅผ ํ†ตํ•œ ์ƒํ˜ธ ๋ฐฐ์ œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฒ˜๋ฆฌ๋  ์ˆ˜ ์žˆ๋‹ค.

while(true) {
    while(compare_and_swap(&lock, 0, 1) != 0)
    	; /* do nothing */
        
    /* critical section */
    
    lock = 0;
    
    /* remainder section */
}

์ „์—ญ๋ณ€์ˆ˜ lock์ด ์„ ์–ธ๋˜๊ณ  0์œผ๋กœ ์ดˆ๊ธฐํ™”๋œ๋‹ค. compare_and_swap()์„ ์ฒ˜์Œ ํ˜ธ์ถœํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ lock์„ 1๋กœ ์„ค์ •ํ•œ๋‹ค. ์›๋ž˜ lock์˜ ๊ฐ’์ด ์˜ˆ์ƒ๊ฐ’ 0๊ณผ ๊ฐ™์œผ๋ฏ€๋กœ ํ”„๋กœ์„ธ์Šค๋Š” ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ„๋‹ค. ์ดํ›„์˜ compare_and_swap() ํ˜ธ์ถœ์€ ํ˜„์žฌ lock์˜ ๊ฐ’์ด ์˜ˆ์ƒ๊ฐ’ 0๊ณผ ๊ฐ™์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๊ณตํ•˜์ง€ ๋ชปํ•œ๋‹ค.  ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์„ ๋ฒ—์–ด๋‚  ๋•Œ๋Š” lock์„ 0์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ณ , ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๊ฒŒ ํ—ˆ์šฉํ•œ๋‹ค.

 

์œ„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ƒํ˜ธ ๋ฐฐ์ œ ์กฐ๊ฑด์€ ๋งŒ์กฑํ•˜์ง€๋งŒ, ํ•œ์ •๋œ ๋Œ€๊ธฐ ์กฐ๊ฑด์„ ๋งŒ์กฑ์‹œํ‚ค์ง€๋Š” ๋ชปํ•œ๋‹ค. ๋‹ค์Œ ์ฝ”๋“œ๋Š” compare_and_swap() ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋ชจ๋“  ์ž„๊ณ„๊ตฌ์—ญ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

while(true) {
    waiting[i] = true;
    key = 1;
    while(waiting[i] && key == 1)
    	key = compare_and_swap(&lock, 0, 1);
    waiting[i] = false;
    
    /* critical section */
    
    j = (i+1) % n;
    while((j != i) && !waiting[j])
    	j = (j+1) % n;
    
    if(j == i)
    	lock = 0;
    else
    	waiting[j] = false;
    
    /* remainder section */
}

 

 

 

6.4.3 ์›์ž์  ๋ณ€์ˆ˜ Atomic Variables

์ผ๋ฐ˜์ ์œผ๋กœ compare_and_swap() ๋ช…๋ น์–ด๋Š” ์ƒํ˜ธ ๋ฐฐ์ œ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ง์ ‘ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ , ์˜คํžˆ๋ ค ์ž„๊ณ„๊ตฌ์—ญ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋‹ค๋ฅธ ๋„๊ตฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋ณธ ๊ตฌ์„ฑ์š”์†Œ๋กœ ์‚ฌ์šฉ๋œ๋‹ค. ๊ทธ๋Ÿฌํ•œ ๋„๊ตฌ ์ค‘ ํ•˜๋‚˜๋Š” ์›์ž์  ๋ณ€์ˆ˜ atomic variable๋กœ, ์ •์ˆ˜ ๋ฐ ๋ถ€์šธ๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ์œ ํ˜•์— ๋Œ€ํ•œ ์›์ž์  ์—ฐ์‚ฐ์„ ์ œ๊ณตํ•œ๋‹ค.

 


๐Ÿ“š 6.5 Mutex Locks

์ž„๊ณ„๊ตฌ์—ญ ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•˜๋“œ์›จ์–ด ๊ธฐ๋ฐ˜ ํ•ด๊ฒฐ์ฑ…์€ ๋ณต์žกํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์‘์šฉ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜๊ฐ€ ์—†๋‹ค. ๋Œ€์‹  ์šด์˜์ฒด์ œ ์„ค๊ณ„์ž๋“ค์€ ์ž„๊ณ„๊ตฌ์—ญ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์ƒ์œ„ ์ˆ˜์ค€ ์†Œํ”„ํŠธ์›จ์–ด ๋„๊ตฌ๋“ค์„ ๊ฐœ๋ฐœํ•˜์˜€๊ณ , ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋„๊ตฌ๊ฐ€ ๋ฐ”๋กœ mutex lock์ด๋‹ค. mutex lock์œผ๋กœ ์ž„๊ณ„๊ตฌ์—ญ์„ ๋ณดํ˜ธํ•˜๊ณ , ๋”ฐ๋ผ์„œ ๊ฒฝ์Ÿ ์กฐ๊ฑด์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด mutex lock์„ ์‚ฌ์šฉํ•œ๋‹ค. ์ฆ‰, ํ”„๋กœ์„ธ์Šค๋Š” ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ€๊ธฐ ์ „์— ๋ฐ˜๋“œ์‹œ ๋ฝ์„ ํš๋“ํ•ด์•ผ ํ•˜๊ณ , ์ž„๊ณ„๊ตฌ์—ญ์—์„œ ๋น ์ ธ๋‚˜์˜ฌ ๋•Œ ๋ฝ์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

์œ„์˜ ๊ทธ๋ฆผ์—์„œ์ฒ˜๋Ÿผ acquire() ํ•จ์ˆ˜๊ฐ€ ๋ฝ์„ ํš๋“ํ•˜๊ณ , release() ํ•จ์ˆ˜๊ฐ€ ๋ฝ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

mutex lock์€ available์ด๋ผ๋Š” boolean ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๋Š”๋ฐ, ์ด ๋ณ€์ˆ˜ ๊ฐ’์ด ๋ฝ์˜ ๊ฐ€์šฉ ์—ฌ๋ถ€๋ฅผ ํ‘œ์‹œํ•œ๋‹ค.

 

acquire()์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•œ๋‹ค.

acquire() {
    while (!available)
    	; /* busy wait */
    available = false;
}

release()๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•œ๋‹ค.

release() {
    available = true;
}

 

acquire()๊ณผ release() ํ•จ์ˆ˜ ํ˜ธ์ถœ์€ ์›์ž์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ mutex lock์€ CAS๋ฅผ ํ†ตํ•ด ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ–ˆ์„ ๋•Œ์˜ ์ตœ๋Œ€ ๋‹จ์ ์€ ๋ฐ”๋กœ ๋ฐ”์œ ๋Œ€๊ธฐ busy waiting์„ ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์— ์žˆ๋Š” ๋™์•ˆ ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ€๊ธฐ๋ฅผ ์›ํ•˜๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋“ค์€ acquire() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐ˜๋ณต๋ฌธ์„ ๊ณ„์† ์‹คํ–‰ํ•ด์•ผ ํ•˜๊ณ , ์ด๋Ÿฌํ•œ ๋ฃจํ”„์˜ ์‹คํ–‰์€ ํ•˜๋‚˜์˜ CPU ์ฝ”์–ด๊ฐ€ ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค์— ๊ณต์œ ๋˜๋Š” ๋ฉ€ํ‹ฐํ”„๋กœ๊ทธ๋ž˜๋ฐ ์‹œ์Šคํ…œ์—์„œ ๋ถ„๋ช…ํžˆ ๋ฌธ์ œ๊ฐ€ ๋œ๋‹ค. 

 


๐Ÿ“š 6.6 Semaphore

mutex์™€ ์œ ์‚ฌํ•˜๊ฒŒ ๋™์ž‘ํ•˜์ง€๋งŒ ํ”„๋กœ์„ธ์Šค๋“ค์ด ์ž์‹ ๋“ค์˜ ํ–‰๋™์„ ๋” ์ •๊ตํ•˜๊ฒŒ ๋™๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๋Š” ๋„๊ตฌ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์ž.

 

์„ธ๋งˆํฌ S๋Š” ์ •์ˆ˜ ๋ณ€์ˆ˜๋กœ์„œ, ์ดˆ๊ธฐํ™”๋ฅผ ์ œ์™ธํ•˜๊ณ ๋Š” ๋‹จ์ง€ ๋‘ ๊ฐ€์ง€์˜ ํ‘œ์ค€ ์›์ž์  ์—ฐ์‚ฐ wait()์™€ signal()๋กœ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

wait()์˜ ์ •์˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

wait(S) {
    while(S <= 0)
    	; // busy wait
    S--;
}

signal()์˜ ์ •์˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

signal(S) {
    S++;
}

 

wait()์™€ signal() ์—ฐ์‚ฐ ์‹œ ์„ธ๋งˆํฌ์˜ ์ •์ˆ˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ์—ฐ์‚ฐ์€ ๋ฐ˜๋“œ์‹œ ์›์ž์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค. ์ฆ‰, ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ์„ธ๋งˆํฌ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด, ๋‹ค๋ฅธ ์–ด๋–ค ์Šค๋ ˆ๋“œ๋„ ๋™์‹œ์— ๋™์ผํ•œ ์„ธ๋งˆํฌ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค.