CS/์šด์˜์ฒด์ œ

[์šด์˜์ฒด์ œ] ch06. Process Synchronization

rngPwns 2025. 4. 21. 08:58

๐Ÿ“„ OS์—์„œ์˜ Race Condition (1/3)

 
์Šฌ๋ผ์ด๋“œ๋Š” ์šด์˜์ฒด์ œ์—์„œ ๋งค์šฐ ์ค‘์š”ํ•œ ๊ฐœ๋…์ธ Race Condition (๊ฒฝ์Ÿ ์กฐ๊ฑด),
๊ทธ ์ค‘์—์„œ๋„ ์ปค๋„ ๋ชจ๋“œ์—์„œ interrupt๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ์˜ ์œ„ํ—˜์„ฑ์„ ์„ค๋ช…ํ•˜๊ณ  ์žˆ์–ด.
"Interrupt handler vs. kernel" ์ƒํ™ฉ์„ ์‹œ๊ฐํ™”ํ•œ ๊ทธ๋ฆผ๊ณผ ํ•จ๊ป˜, ์‹ค์Šต์ฒ˜๋Ÿผ ๋ ˆ์ง€์Šคํ„ฐ ๊ฐ’์„ ๋”ฐ๋ผ๊ฐ€๋ฉฐ ์„ค๋ช…ํ•˜๋Š” ๊ตฌ์กฐ์•ผ.
 

interrupt handler vs. kernel


๐Ÿง  ํ•ต์‹ฌ ๊ฐœ๋… ์š”์•ฝ

Race Condition:
๋‘˜ ์ด์ƒ์˜ ํ”„๋กœ์„ธ์Šค(๋˜๋Š” interrupt)๊ฐ€ **๊ณต์œ  ์ž์›(์˜ˆ: count ๋ณ€์ˆ˜)**์— ๋™์‹œ ์ ‘๊ทผํ•˜๋ฉด์„œ
์˜๋„ํ•˜์ง€ ์•Š์€ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ.


๐Ÿ” ๋ฐœ์ƒ ์ƒํ™ฉ ์‹œ๋‚˜๋ฆฌ์˜ค

  • count++ ์ˆ˜ํ–‰ ์‹œ ๋‚ด๋ถ€์ ์œผ๋กœ ๋‹ค์Œ ์ˆœ์„œ๋กœ ์ฒ˜๋ฆฌ๋จ:
    1. load count โ†’ ๋ ˆ์ง€์Šคํ„ฐ R1 โ† count (์˜ˆ: 10)
    2. inc R1 โ†’ R1 โ† 11
    3. store R1 โ†’ count

๐Ÿšจ ์œ„ํ—˜ ์ƒํ™ฉ

  1. ์‚ฌ์šฉ์ž๊ฐ€ count++ ์‹คํ–‰ ์ค‘ (Kernel mode์—์„œ ์‹คํ–‰ ์ค‘)
  2. ์ด ๋•Œ ์ธํ„ฐ๋ŸฝํŠธ ๋ฐœ์ƒ
  3. โ†’ ์ธํ„ฐ๋ŸฝํŠธ ํ•ธ๋“ค๋Ÿฌ๋„ ๊ฐ™์€ count++ ์ˆ˜ํ–‰
  4. ๋‘ ๊ณณ ๋ชจ๋‘ ๊ฐ™์€ count ์ฃผ์†Œ ์ฐธ์กฐ (๊ณต์œ  ๋ณ€์ˆ˜)
    โ†’ ๊ฐ’์ด ๊ผฌ์ž„ (Race ๋ฐœ์ƒ)

๐Ÿ“Œ ๋ฌธ์ œ์˜ ํ•ต์‹ฌ

  • 10 โ†’ 11๋กœ ์˜ฌ๋ผ๊ฐ€์•ผ ํ•˜๋Š”๋ฐ,
    ๋‘˜ ๋‹ค load ์‹œ์ ์—์„œ 10์„ ์ฝ์Œ โ†’ ๋‘˜ ๋‹ค 11๋กœ ๋งŒ๋“ค๊ณ  ์ €์žฅ
    โ†’ ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋‘ ๋ฒˆ ์ฆ๊ฐ€ํ•ด์•ผ ํ•  ๊ฐ’์ด ํ•œ ๋ฒˆ๋งŒ ์ฆ๊ฐ€๋จ

โœ๏ธ ์Šฌ๋ผ์ด๋“œ ํ•„๊ธฐ ์ •๋ฆฌ

  • โ€œ๋‘˜ ๋‹ค 10์—์„œ ์‹œ์ž‘ํ•ด์„œ 11๋กœ ์ €์žฅํ•จ โ†’ ํ•˜๋‚˜๋งŒ ๋ฐ˜์˜๋จโ€
  • โ€œCPU์— ์ €์žฅ๋œ register ๊ฐ’ ๋ณต๊ตฌ๋จ โ†’ ์ด์ „ ๊ฐ’์ด ๋ฎ์–ด์จ์งโ€
  • โ€œ์ปค๋„ ๋ชจ๋“œ ์ค‘ ์ธํ„ฐ๋ŸฝํŠธ ๊ฑธ๋ฆฌ๋ฉด ์œ„ํ—˜โ€
  • โ€œcontext switch ๋ฐœ์ƒ โ†’ count ๊ฐ’ ์œ ์‹ค ๊ฐ€๋Šฅโ€
  • โ€œkernel ๋ชจ๋“œ ์‹คํ–‰ ์ค‘ disable interrupt ํ•„์š”โ€
  • ์•„๋ž˜์ชฝ ์„ค๋ช…: if you preempt CPU while in kernel mode โ€ฆ โ†’ ๋ฌธ์ œ ๋ฐœ์ƒ ์กฐ๊ฑด ์š”์•ฝ

โœ… ์•”๊ธฐ ํฌ์ธํŠธ

  • Race Condition์€ ๊ณต์œ  ์ž์›๊ณผ ๋น„๋™๊ธฐ ์ ‘๊ทผ์ด ๋™์‹œ์— ์ผ์–ด๋‚  ๋•Œ ๋ฐœ์ƒ
  • ํŠนํžˆ **count++, count--**๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ 3๋‹จ๊ณ„ โ†’ ์ค‘๊ฐ„์— ๋ผ์–ด๋“ค๋ฉด ๋ฌธ์ œ ๋ฐœ์ƒ
  • ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:
    • Interrupt disable/enable๋กœ ๋ณดํ˜ธ
    • Lock, Mutex, Semaphore๋กœ ๋™๊ธฐํ™”
  • ์ปค๋„ ๋ชจ๋“œ ์ค‘ preemption/interruption ๊ธˆ์ง€๊ฐ€ ํ•ต์‹ฌ

โœ๏ธ ์ •๋ฆฌ ๋ฌธ์žฅ

"Kernel ๋ชจ๋“œ์—์„œ ๊ณต์œ  ๋ณ€์ˆ˜ ์ ‘๊ทผ ์ค‘ interrupt๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด
Interrupt handler๋„ ๋™์ผ ์ž์›์„ ์ˆ˜์ •ํ•˜๊ฒŒ ๋˜์–ด race condition์ด ๋ฐœ์ƒํ•œ๋‹ค."


์ด๊ฑด Race Condition์˜ ๊ตฌ์กฐ์  ๋ฐœ์ƒ ์ด์œ ์™€ ๋ฐฉ์ง€ ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋Š” ๊ฐ€์žฅ ์ „ํ˜•์ ์ธ ์Šฌ๋ผ์ด๋“œ์•ผ.
 
 
 
 

๐Ÿ“„ If you preempt CPU while in kernel mode โ€ฆ

์ด๋ฒˆ ์Šฌ๋ผ์ด๋“œ๋Š” ์•ž์„  ๋‚ด์šฉ๊ณผ ์—ฐ๊ด€๋œ Race Condition์˜ ์‹ค์งˆ์ ์ธ ์˜ˆ์‹œ ์ƒํ™ฉ์„ ๋‹ค๋ฃจ๊ณ  ์žˆ์–ด.
ํŠนํžˆ, "์ปค๋„ ๋ชจ๋“œ ์ค‘ preemption(์„ ์ )์ด ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ" ์–ด๋–ค ์ผ์ด ์ƒ๊ธฐ๋Š”์ง€๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ์„ค๋ช…ํ•˜๊ณ  ์žˆ์–ด.
๐Ÿ“Œ ์Šฌ๋ผ์ด๋“œ์— ๊ทธ๋ ค์ง„ ํƒ€์ž„๋ผ์ธ, ์‹œ์Šคํ…œ ์ฝœ ํ๋ฆ„, count ๊ฐ’ ๋ณ€ํ™”, ๊ทธ๋ฆฌ๊ณ  ๋นจ๊ฐ„ ํ•„๊ธฐ๊นŒ์ง€ ํฌํ•จํ•ด์„œ ์ •๋ฆฌํ• ๊ฒŒ!


๐Ÿ“„ If you preempt CPU while in kernel mode โ€ฆ


๐Ÿง  ๋ฐฐ๊ฒฝ ์„ค๋ช…

**์ปค๋„ ๋ชจ๋“œ(kernel mode)**๋Š” ์šด์˜์ฒด์ œ์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์ด ์‹คํ–‰๋˜๋Š” ํŠน์ˆ˜ ๊ถŒํ•œ ๋ชจ๋“œ์•ผ.
๋งŒ์•ฝ ์ด ์ƒํƒœ์—์„œ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ **CPU๋ฅผ ์„ ์ (preempt)**ํ•œ๋‹ค๋ฉดโ€ฆ
โž Race Condition์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ โš ๏ธ


๐Ÿงต ์‹œ๋‚˜๋ฆฌ์˜ค ์š”์•ฝ

(1) ํ”„๋กœ์„ธ์Šค A (Pโ‚)

  • ์‚ฌ์šฉ์ž ๋ชจ๋“œ โ†’ ์‹œ์Šคํ…œ ์ฝœ read() ํ˜ธ์ถœ โ†’ ์ปค๋„ ๋ชจ๋“œ ์ง„์ž…
  • ์ปค๋„์—์„œ count++ ์ˆ˜ํ–‰ ์ค‘์ด์—ˆ์Œ (์•„์ง ์™„๋ฃŒ๋˜์ง€ ์•Š์Œ!)

(2) ํƒ€์ž„ํ€€ํ…€ ์ข…๋ฃŒ & ํ”„๋กœ์„ธ์Šค B (P_b)๊ฐ€ CPU ์š”๊ตฌ

  • Pโ‚๋Š” ์ปค๋„ ๋ชจ๋“œ ์ƒํƒœ์—์„œ preempt ๋‹นํ•จ
  • P_b๊ฐ€ ์ปค๋„์— ์ง„์ž…ํ•ด count ๋ณ€์ˆ˜ ์‚ฌ์šฉ
  • P_b๊ฐ€ count ์ˆ˜์ •ํ•œ ๋’ค โ†’ ๋‹ค์‹œ Pโ‚ ๋ณต๊ท€ โ†’ Pโ‚๊ฐ€ ์ด์ „ register ๊ฐ’์œผ๋กœ count ๋ฎ์–ด์”€!

โ†’ ๐Ÿ”ฅ ๊ฒฐ๊ตญ count = 10 โ†’ 9 โ†’ 11๋กœ ์˜ค์—ผ๋จ (์˜ฌ๋ฐ”๋ฅธ ๊ฐ’ ์•„๋‹˜)


๐Ÿ“Œ ์Šฌ๋ผ์ด๋“œ ํ•„๊ธฐ ์š”์•ฝ

  • โ€œcount๊ฐ’์ด 10โ†’9โ†’11 ์ด์ƒํ•˜๊ฒŒ ๋ฐ”๋€œโ€
  • โ€œCPU ๋˜๋Œ๋ ค ๋ฐ›์Œ โ†’ ์ด์ „ ๊ฐ’์œผ๋กœ ๋ฎ์–ด์“ฐ๊ธฐโ€
  • โ€œINC/STORE โ†” LOAD/DEC/STORE ์‚ฌ์ดํด ์ถฉ๋Œโ€
  • "ํ•ด๊ฒฐ์ฑ…์ด ์•„๋‹Œ 'ํšŒํ”ผ์ฑ…' = ์ปค๋„ ๋ชจ๋“œ์—์„œ๋Š” preemptํ•˜์ง€ ์•Š๋„๋ก"

โœ… ํ•ด๊ฒฐ/ํšŒํ”ผ ๋ฐฉ์•ˆ

๊ตฌ๋ถ„์„ค๋ช…
๐Ÿ”’ ํ•ด๊ฒฐ์ฑ… Critical Section ๋ณดํ˜ธ (์˜ˆ: Mutex, Semaphore, Spinlock ๋“ฑ)
โš ๏ธ ํšŒํ”ผ์ฑ… ์ปค๋„ ๋ชจ๋“œ์—์„œ๋Š” CPU๋ฅผ preemptํ•˜์ง€ ์•Š์Œ
๐Ÿง  ์‹ค์ œ ์ ์šฉ Linux๋Š” preempt ๊ฐ€๋Šฅํ•˜๋˜ **preempt_disable/enable()**๋กœ ๊ตฌ๊ฐ„ ๋ณดํ˜ธ

ํ•ต์‹ฌ ๋ฌธ์žฅ ์ •๋ฆฌ

โ€œ์ปค๋„ ๋ชจ๋“œ์—์„œ count๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ์ค‘๊ฐ„์— preempt๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด,
์ด์ „ ๊ฐ’์ด ๋ฎ์–ด์”Œ์›Œ์ ธ Race Condition์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ปค๋„ ๋ชจ๋“œ์—์„œ๋Š” preemption์„ ๋ง‰๊ฑฐ๋‚˜, ๋™๊ธฐํ™”๋ฅผ ํ†ตํ•ด ๋ณดํ˜ธํ•ด์•ผ ํ•œ๋‹ค.โ€


๐Ÿ’ก ์‹œํ—˜ ๋Œ€๋น„ ํŒ

  • count++๋ฅผ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” load โ†’ inc โ†’ store ํ˜•ํƒœ๋กœ ์ฒ˜๋ฆฌํ•จ์„ ๋ฐ˜๋“œ์‹œ ๊ธฐ์–ต!
  • ์‚ฌ์šฉ์ž ๋ชจ๋“œ <-> ์ปค๋„ ๋ชจ๋“œ ์ „ํ™˜ ์‹œ interrupt/preempt๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด Race ๋ฐœ์ƒ ๊ฐ€๋Šฅ
  • ํ•ด๊ฒฐ์ฑ… ๊ตฌ์ฒด์ ์œผ๋กœ ์ œ์‹œํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ (preempt ๋ง‰๊ธฐ, lock ์‚ฌ์šฉ ๋“ฑ)

์ด ์Šฌ๋ผ์ด๋“œ๋Š” ์šด์˜์ฒด์ œ์˜ ์‹ค์ œ context switching๊ณผ interrupt/preemption ํƒ€์ด๋ฐ์ด ์–ผ๋งˆ๋‚˜ ์œ„ํ—˜ํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ์„ค๋ช…ํ•˜๋Š” ํ•ต์‹ฌ ์˜ˆ์‹œ์•ผ.
 
 
 
 

๐Ÿ“„ OS์—์„œ์˜ Race Condition (2/3)

๐Ÿงฉ Preempt a process running in kernel?


๐Ÿง  ํ•ต์‹ฌ ๊ฐœ๋…

Race Condition์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฑด ๋‹จ์ˆœํžˆ preemption ๋•Œ๋ฌธ์ด ์•„๋‹ˆ๋ผ,
"**๊ณต์œ  ์ž์›(Shared Data)**์„ ๋™์‹œ์— ์ ‘๊ทผํ•˜๋ฉด์„œ๋„ Critical Section์ด ๋ณดํ˜ธ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ"์—๋งŒ ํ•ด๋‹น๋ผ.


๐Ÿงต ์‹œ๋‚˜๋ฆฌ์˜ค ์š”์•ฝ

โœฆ ํ”„๋กœ์„ธ์Šค Pโ‚

  • ์‚ฌ์šฉ์ž ๋ชจ๋“œ โ†’ ์ปค๋„ ๋ชจ๋“œ ์ง„์ž…
  • ์ปค๋„์—์„œ ๊ณต์œ  ์ž์›(count++) ์ˆ˜ํ–‰ ์ค‘

โœฆ ๊ทธ ์ˆœ๊ฐ„, ํ”„๋กœ์„ธ์Šค P_b๊ฐ€ system call ์š”์ฒญ

  • CPU๋ฅผ ์„ ์ ๋ฐ›์•„ ์ปค๋„ ์ง„์ž…
  • ์—ญ์‹œ ๊ณต์œ  ์ž์›(count--) ์ˆ˜ํ–‰
  • ๋‘ ์ปค๋„ ๋ชจ๋“œ๊ฐ€ ๋™์‹œ์— ์ปค๋„ ์ฃผ์†Œ ๊ณต๊ฐ„์„ ๊ณต์œ 
    โ†’ ์ด๋•Œ Race Condition ๋ฐœ์ƒ ์œ„ํ—˜ ์žˆ์Œ

๐Ÿ“Œ ํ•„๊ธฐ ๋‚ด์šฉ ์ •๋ฆฌ

  • "์—ฌ๊ธฐ์„œ c.s(Critical Section) ์ผ์–ด๋‚  ๋•Œ ๋ฌธ์ œ"
  • "PA๋Š” count++, PB๋Š” count-- ์ค‘ โ†’ ๋‘˜ ๋‹ค count ์ ‘๊ทผ"
  • "์—ฌ๊ธฐ์„œ๋Š” context switch ์ผ์–ด๋‚˜๋„ ๋ฌธ์ œ X"
    โ†’ โ†’ user mode ์ค‘์—๋Š” address space๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์–ด ๋ฌธ์ œ ์—†์Œ

โญ ํ•ต์‹ฌ ์š”์  ๋น„๊ต

์ƒํ™ฉ์„ค๋ช…Race Condition ๋ฐœ์ƒ ์—ฌ๋ถ€
PA ์ปค๋„ ๋ชจ๋“œ ์ค‘ preempt ๋จ count++ ์ค‘๊ฐ„์— ๋ผ์–ด๋“ค๋ฉด โ†’ PB๊ฐ€ count ์ˆ˜์ • โœ… ๋ฐœ์ƒ ์œ„ํ—˜
PA user mode์ผ ๋•Œ preempt ๊ฐ์ž ๋‹ค๋ฅธ address space โ†’ ๊ณต์œ  ์—†์Œ โŒ ์—†์Œ

๐Ÿ“Œ ์Šฌ๋ผ์ด๋“œ ํ•˜๋‹จ ์„ค๋ช… ์ •๋ฆฌ

  • * ์‚ฌ์šฉ์ž address space๋Š” ๊ณต์œ ๋˜์ง€ ์•Š์Œ
  • ** ํ•˜์ง€๋งŒ system call ์ค‘์—๋Š” kernel address space๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋จ (๊ณต์œ  ์ž์› ์กด์žฌ)
  • *** โ†’ ๊ทธ ์ƒํƒœ์—์„œ preempt๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด Race ๋ฐœ์ƒ ๊ฐ€๋Šฅ์„ฑ ์žˆ์Œ

โœ… ์•”๊ธฐ ํฌ์ธํŠธ

  • Race Condition์€ ๊ณต์œ ๋œ ์ž์›์— ๋Œ€ํ•ด ๋น„๋™๊ธฐ ์ ‘๊ทผ์ด ์žˆ์„ ๋•Œ ๋ฐœ์ƒ
  • ์ปค๋„ ๋ชจ๋“œ๋ผ๋ฆฌ๋Š” ์ฃผ์†Œ ๊ณต๊ฐ„์„ ๊ณต์œ ํ•จ โ†’ ์œ„ํ—˜ํ•จ
  • user mode์—์„œ๋Š” ๊ฐ์ž์˜ ๊ณต๊ฐ„์„ ์‚ฌ์šฉ โ†’ ์•ˆ์ „ํ•จ
  • ํ•ด๊ฒฐ๋ฒ•: critical section ๋ณดํ˜ธ / ์ปค๋„ ๋ชจ๋“œ ์ค‘ preempt ๋ฐฉ์ง€

โœ๏ธ ์ •๋ฆฌ ๋ฌธ์žฅ

โ€œ์ปค๋„ ๋ชจ๋“œ์—์„œ system call ์ˆ˜ํ–‰ ์ค‘ preempt๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด,
๋‘ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฐ™์€ ์ปค๋„ ์ž์›(count ๋“ฑ)์„ ์ ‘๊ทผํ•˜์—ฌ Race Condition์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
๋ฐ˜๋ฉด user mode์—์„œ๋Š” ์ฃผ์†Œ ๊ณต๊ฐ„์ด ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์•ˆ์ „ํ•˜๋‹ค.โ€

 
 
 

๐Ÿ“„ OS์—์„œ์˜ Race Condition (3/3)

๐Ÿ” Multiprocessor ํ™˜๊ฒฝ์—์„œ์˜ ๊ฒฝ์Ÿ ์กฐ๊ฑด


๐Ÿ“Œ ํ•ต์‹ฌ ๊ฐœ๋…

Multiprocessor ์‹œ์Šคํ…œ์—์„œ๋Š” ์—ฌ๋Ÿฌ CPU๊ฐ€ ๋™์‹œ์— **๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ(์˜ˆ: count ๋ณ€์ˆ˜)**์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Œ.
โ†’ ํ•œ CPU๊ฐ€ count++ ์ค‘์ผ ๋•Œ, ๋‹ค๋ฅธ CPU๊ฐ€ ๋™์‹œ์— count--๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด Race Condition ๋ฐœ์ƒ.


๐Ÿงต ์ƒํ™ฉ ํ๋ฆ„ ์š”์•ฝ

CPU โ‘ 

  • count++ ์ˆ˜ํ–‰ ์ค‘
  • ๋‚ด๋ถ€ ๋™์ž‘: LOAD(10) โ†’ INC(11) โ†’ STORE(11)

๋™์‹œ์— CPU โ‘ก

  • count-- ์ˆ˜ํ–‰
  • ๋‚ด๋ถ€ ๋™์ž‘: LOAD(10) โ†’ DEC(9) โ†’ STORE(9)

๐Ÿงจ ๊ฒฐ๊ณผ: ๋‘˜ ๋‹ค ๋™์ผํ•œ ์ดˆ๊ธฐ ๊ฐ’ 10์„ ์ฝ๊ณ , ๊ฐ๊ฐ ๋ฎ์–ด์“ฐ๊ธฐ โ†’ ๊ฒฐ๊ณผ๊ฐ€ ๊ผฌ์ž„


๐Ÿ’ฅ ๋ฌธ์ œ ํ•ต์‹ฌ

โ— ์–ด๋–ค CPU๊ฐ€ ๋งˆ์ง€๋ง‰์— STORE๋ฅผ ํ–ˆ๋Š”๊ฐ€์— ๋”ฐ๋ผ count ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์ง
โ†’ interrupt disable/enable๋งŒ์œผ๋กœ ํ•ด๊ฒฐ ๋ถˆ๊ฐ€
(์™œ๋ƒํ•˜๋ฉด CPU๋งˆ๋‹ค ๋ณ„๋„ interrupt controller๊ฐ€ ์žˆ์Œ)


โœ ์Šฌ๋ผ์ด๋“œ ํ•„๊ธฐ ์š”์•ฝ

  • โ€œ์–ด๋–ค CPU๊ฐ€ ๋งˆ์ง€๋ง‰์œผ๋กœ store ํ–ˆ๋Š”๊ฐ€ โ†’ Race ๋ฐœ์ƒ ์›์ธโ€
  • โ€œMultiprocessor๋Š” interrupt ์ œ์–ด๋งŒ์œผ๋กœ๋Š” ํ•ด๊ฒฐ ๋ถˆ๊ฐ€๋Šฅโ€
  • ๋ฐฉ๋ฒ• โ‘ : โ€œ1๊ฐœ๋งŒ ์ปค๋„ ์ง„์ž… ํ—ˆ์šฉ โ†’ ๋น„ํšจ์œจ์ โ€
  • ๋ฐฉ๋ฒ• โ‘ก: โ€œ๊ณต์œ  ๋ฐ์ดํ„ฐ๋งˆ๋‹ค lock/unlock ์ ์šฉ โ†’ ์ •์„์  ํ•ด๊ฒฐโ€

๐Ÿ” ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• 2๊ฐ€์ง€

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ค๋ช…๋‹จ์ 
๋ฐฉ๋ฒ• โ‘  ํ•œ๋ฒˆ์— 1๊ฐœ์˜ CPU๋งŒ ์ปค๋„ ์ง„์ž… ํ—ˆ์šฉ ์ปค๋„ ์ ‘๊ทผ ์†๋„ ๋А๋ฆผ, ๋ณ‘๋ ฌ์„ฑ ์ €ํ•˜
๋ฐฉ๋ฒ• โ‘ก ๊ณต์œ  ์ž์›์— ๋Œ€ํ•ด lock/unlock ์‚ฌ์šฉ lock ์„ค๊ณ„ ์ž˜๋ชปํ•˜๋ฉด deadlock, starvation ๊ฐ€๋Šฅ

โ†’ โœ ํ•„๊ธฐ: โ€œlock ์ž์ฒด๊ฐ€ ๋ฌธ์ œ์„ฑ Oโ€


๐Ÿ’ก ์ •๋ฆฌ ๋ฌธ์žฅ

โ€œMultiprocessor ํ™˜๊ฒฝ์—์„œ๋Š” ๊ณต์œ  ์ž์›์— ๋Œ€ํ•œ ๋™๊ธฐํ™” ์—†์ด ์—ฌ๋Ÿฌ CPU๊ฐ€ ์ ‘๊ทผํ•  ๊ฒฝ์šฐ
Race Condition์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” lock/unlock์„ ํ†ตํ•œ ๋ณดํ˜ธ๊ฐ€ ํ•„์ˆ˜์ ์ด๋‹ค.โ€


โœ… ์•”๊ธฐ ํฌ์ธํŠธ

  • count++, count--๋Š” atomic operation์ด ์•„๋‹˜!
  • Multiprocessor ํ™˜๊ฒฝ์—์„œ๋Š” disable interrupt๋กœ๋Š” ๋ณดํ˜ธ ๋ถˆ๊ฐ€
  • ๋ฐ˜๋“œ์‹œ lock ๋˜๋Š” atomic ์—ฐ์‚ฐ ์ง€์› ๊ธฐ๋ฒ• ํ•„์š” (e.g., test-and-set, compare-and-swap ๋“ฑ)
  • ์‹ค์Šต/์ด๋ก /์ฝ”๋“œ ๊ตฌํ˜„ ์ „๋ถ€์—์„œ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋Š” ์ฃผ์ œ

์ด ์Šฌ๋ผ์ด๋“œ๋Š” ๋™๊ธฐํ™”์˜ ํ•„์š”์„ฑ, ํŠนํžˆ Multiprocessor ํ™˜๊ฒฝ์—์„œ์˜ ๊ตฌ์กฐ์  Race Condition์„ ์‹œ๊ฐ์ ์œผ๋กœ ์„ค๋ช…ํ•˜๋Š” ๋งˆ๋ฌด๋ฆฌ ์žฅ๋ฉด์ด์•ผ.
"๋™์‹œ ์ ‘๊ทผ + ๋ฏธ๋ณดํ˜ธ โ†’ ๊ผฌ์ž„ ๋ฐœ์ƒ" ๊ณต์‹์ฒ˜๋Ÿผ ์™ธ์›Œ๋‘ฌ๋„ ์ข‹์•„!
 
 

๐Ÿ“„ Example of a Race Condition

(๊ณต์œ  ์ž์›์— ๋Œ€ํ•œ ๋น„๋™๊ธฐ ์ ‘๊ทผ ๋ฌธ์ œ)


๐Ÿง  ํ•ต์‹ฌ ๊ฐœ๋…

์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋™์‹œ์— ํ•˜๋‚˜์˜ ๊ณต์œ  ๋ณ€์ˆ˜ X์— ์ ‘๊ทผํ•ด์„œ ๊ฐ’์„ ์ˆ˜์ •ํ•˜๋Š”๋ฐ,
์ž‘์—… ์ˆœ์„œ์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์ง€๋Š” ์ƒํ™ฉ์ด ๋ฐ”๋กœ Race Condition!


๐Ÿ“Œ ์Šฌ๋ผ์ด๋“œ ๊ตฌ์„ฑ

๐Ÿงฑ ๊ณต์œ  ๋ณ€์ˆ˜

  • X = 2 (์ดˆ๊ธฐ๊ฐ’)

๐Ÿ” ์—ฐ์‚ฐ ๋ชฉ์ 

  • P1: X = X + 1 โ†’ ๊ธฐ๋Œ€๊ฐ’: 3
  • P2: X = X - 1 โ†’ ๊ธฐ๋Œ€๊ฐ’: 1

๐Ÿงฎ ๋‚ด๋ถ€ ์—ฐ์‚ฐ (P1 / P2)

Process๋‚ด๋ถ€ ์—ฐ์‚ฐ (๋ช…๋ น์–ด ์‹œํ€€์Šค)
P1 load X โ†’ reg1
inc reg1
store reg1 โ†’ X
P2 load X โ†’ reg2
dec reg2
store reg2 โ†’ X

๐Ÿ’ฅ Race ๋ฐœ์ƒ ์ƒํ™ฉ ์˜ˆ์‹œ

  1. P1์ด X=2๋ฅผ reg1์— ๋กœ๋“œํ•˜๊ณ  ์•„์ง store ์•ˆ ํ•œ ์ƒํƒœ
  2. ๊ทธ ์‚ฌ์ด์— ํƒ€์ด๋จธ ์ธํ„ฐ๋ŸฝํŠธ(context switch) ๋ฐœ์ƒ โ†’ P2๊ฐ€ CPU ์ ์œ 
  3. P2๋Š” X๋ฅผ ์ฝ๊ณ  ๊ฐ์†Œ โ†’ X=1 ์ €์žฅ
  4. ๋‹ค์‹œ P1 ๋ณต๊ท€ โ†’ X=3 ์ €์žฅ

๐Ÿ”ป ๊ฒฐ๊ณผ: X = 2 โ†’ 1 โ†’ 3
โ†’ P2์˜ ๋ณ€๊ฒฝ ๋‚ด์šฉ(1)์ด ์‚ฌ๋ผ์ง = Race Condition ๋ฐœ์ƒ


โœ ์Šฌ๋ผ์ด๋“œ ํ•„๊ธฐ ์š”์•ฝ

  • โ€œ์‚ฌ์šฉ์ž ํ”„๋กœ์„ธ์Šค P1 ์ˆ˜ํ–‰ ์ค‘ timer interrupt๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ P2๊ฐ€ CPU๋ฅผ ์–ป๊ฒŒ ๋˜๋ฉด?โ€
    โ†’ Critical Section ๋ณดํ˜ธ ์—†์œผ๋ฉด P2์˜ ์ž‘์—…์ด ๋ฌด์‹œ๋  ์ˆ˜ ์žˆ์Œ

โœ… ํ•ต์‹ฌ ์ •๋ฆฌ

ํ•ญ๋ชฉ๋‚ด์šฉ
๋ฐœ์ƒ ์กฐ๊ฑด ๊ณต์œ  ์ž์›(X)์„ ๋™์‹œ์— ์ˆ˜์ •ํ•˜๋Š” ๋‘ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ์Œ
๋ฌธ์ œ ์›์ธ ์—ฐ์‚ฐ ๋‹จ์œ„(loadโ€“incโ€“store)๊ฐ€ **์›์ž์ (atomic)**์ด์ง€ ์•Š์Œ
ํ•ด๊ฒฐ ํ•„์š” ์—ฐ์‚ฐ ์ „์ฒด๋ฅผ ํ•˜๋‚˜์˜ Critical Section์œผ๋กœ ๋ฌถ์–ด์•ผ ํ•จ

๐Ÿงฉ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ ์š”์•ฝ

  • Lock ์‚ฌ์šฉ: lock(X) โ†’ ์—ฐ์‚ฐ โ†’ unlock(X)
  • Atomic ์—ฐ์‚ฐ ๋„์ž…: Test-and-set, Compare-and-swap ๋“ฑ
  • ์ปค๋„ ๋ ˆ๋ฒจ ๋ณดํ˜ธ: preempt disable, spinlock ๋“ฑ ์‚ฌ์šฉ

๐Ÿ’ก ์•”๊ธฐ์šฉ ๋ฌธ์žฅ

"Race Condition์€ ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ณต์œ  ์ž์›์— ๋Œ€ํ•ด ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ ‘๊ทผํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋ฉฐ,
์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์—ฐ์‚ฐ์„ Atomicํ•˜๊ฒŒ ๋งŒ๋“ค๊ฑฐ๋‚˜ Lock์œผ๋กœ ๋ณดํ˜ธํ•ด์•ผ ํ•œ๋‹ค."


์ด ์Šฌ๋ผ์ด๋“œ๋Š” Race Condition์˜ ๊ฐ€์žฅ ๊ธฐ์ดˆ์ ์ด๊ณ  ์ž์ฃผ ์ถœ์ œ๋˜๋Š” ํ˜•ํƒœ์ด๋ฏ€๋กœ,
์—ฐ์‚ฐ ๋‹จ์œ„ / context switch ์‹œ์  / ๊ฒฐ๊ณผ ๊ผฌ์ž„ ์ด์œ ๋ฅผ ์ •ํ™•ํžˆ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ด!
 
 

๐Ÿ“„ Algorithm 1 โ€“ Mutual Exclusion using turn only

๐Ÿ”‘ ํ•ต์‹ฌ ์•„์ด๋””์–ด

ํ•˜๋‚˜์˜ ๊ณต์œ  ๋ณ€์ˆ˜ turn์„ ํ†ตํ•ด ๋‘˜ ์ค‘ ํ•˜๋‚˜๋งŒ CS์— ๋“ค์–ด๊ฐ€๋„๋ก ์ œ์–ดํ•œ๋‹ค.


๐Ÿ“Œ ์‚ฌ์šฉ ๋ณ€์ˆ˜

c
์ฝ”๋“œ ๋ณต์‚ฌ
int turn = 0;
  • turn == 0: ํ”„๋กœ์„ธ์Šค Pโ‚€๊ฐ€ ์ง„์ž… ๊ฐ€๋Šฅ
  • turn == 1: ํ”„๋กœ์„ธ์Šค Pโ‚๊ฐ€ ์ง„์ž… ๊ฐ€๋Šฅ
  • ์ฆ‰, ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค๋งŒ ํ—ˆ์šฉ๋˜๋ฉฐ, CS๋ฅผ ๋น ์ ธ๋‚˜์˜จ ์ชฝ์ด ํ„ด์„ ๋„˜๊ฒจ์คŒ

๐Ÿงฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌ์กฐ

๐Ÿ”น ํ”„๋กœ์„ธ์Šค Pโ‚€

c
์ฝ”๋“œ ๋ณต์‚ฌ
do { while (turn != 0); // ์ƒ๋Œ€์˜ ํ„ด์ด๋ฉด ๊ธฐ๋‹ค๋ฆผ // Critical Section turn = 1; // ์ƒ๋Œ€์—๊ฒŒ ํ„ด ๋„˜๊น€ // Remainder Section } while (1);

๐Ÿ”น ํ”„๋กœ์„ธ์Šค Pโ‚

c
์ฝ”๋“œ ๋ณต์‚ฌ
do { while (turn != 1); // ๋‚ด ํ„ด ์•„๋‹ˆ๋ฉด ๊ธฐ๋‹ค๋ฆผ // Critical Section turn = 0; // ํ„ด ๋„˜๊น€ // Remainder Section } while (1);

๐Ÿ“ ํ•„๊ธฐ ์š”์•ฝ ์ •๋ฆฌ

  • while(turn != i) ์กฐ๊ฑด์€ ๋‚ด ํ„ด์ด ๋  ๋•Œ๊นŒ์ง€ **๋ฌดํ•œ ๋Œ€๊ธฐ(loop)**ํ•จ
  • ํ•„๊ธฐ์—์„œ ๊ฐ•์กฐํ•œ ๊ฒƒ์ฒ˜๋Ÿผ:
    • ๋‘˜ ๋‹ค CS์— ๋“ค์–ด๊ฐ€๋ ค๊ณ  ํ•ด๋„, turn์€ ํ•˜๋‚˜๋งŒ ์—ด์–ด์ฃผ๋ฏ€๋กœ Mutual Exclusion์€ OK
    • ํ•˜์ง€๋งŒ ์ƒ๋Œ€๊ฐ€ Remainder Section์— ๋จธ๋ฌผ๋Ÿฌ๋„ ๋‚ด ํ„ด์ด ์•„๋‹ˆ๋ฉด ๋‚˜๋Š” ๋ฌด์กฐ๊ฑด ๊ธฐ๋‹ค๋ฆผ
      • ์ด๊ฒŒ ๋ฐ”๋กœ Progress ์กฐ๊ฑด์„ ์œ„๋ฐ˜ํ•˜๋Š” ๊ฒƒ

๐Ÿ” ์กฐ๊ฑด ํ‰๊ฐ€

์กฐ๊ฑด๋งŒ์กฑ ์—ฌ๋ถ€์„ค๋ช…
Mutual Exclusion โœ… ๋งŒ์กฑ ๋™์‹œ์— CS ์ง„์ž… ๋ถˆ๊ฐ€
Progress โŒ ๋ถˆ๋งŒ์กฑ ๋‘˜ ๋‹ค CS ์›ํ•ด๋„ turn์ด ์•ˆ ๋ฐ”๋€Œ๋ฉด ๋ฌดํ•œ ๋Œ€๊ธฐ
Bounded Waiting โŒ ๋ถˆ๋งŒ์กฑ ํ„ด์ด ์˜์›ํžˆ ๋Œ์•„์˜ค์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ

๐Ÿ“Œ ํ•ต์‹ฌ ํ•„๊ธฐ ํ•ด์„

  • * ๋‹จ์ˆœํ•˜๊ฒŒ swap-turn ๋ฐฉ์‹
  • * Pโ‚€, Pโ‚ ๋‘˜ ๋‹ค critical section ์›ํ•˜๋ฉด turn์ด ์•ˆ ๋ฐ”๋€Œ์–ด ๋ฉˆ์ถค
  • * "์ด๊ฑด mutual exclusion๋งŒ ๋งŒ์กฑํ•˜๊ณ  ๋‚˜๋จธ์ง€๋Š” ๋ถˆ๋งŒ์กฑ"
  • โžค ๊ทธ๋ž˜์„œ ์ด ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ **Peterson's Algorithm (Algorithm 3)**๊ฐ€ ๋“ฑ์žฅํ•œ ๊ฑฐ์•ผ

โœ… ์•”๊ธฐ ํฌ์ธํŠธ

  • turn ๋ณ€์ˆ˜๋งŒ ์‚ฌ์šฉ โ†’ ์ƒํ˜ธ๋ฐฐ์ œ OK
  • ์ง„์ž… ์˜๋„ ํ‘œํ˜„ X โ†’ ์ง„ํ–‰์„ฑ ๋ฌธ์ œ ๋ฐœ์ƒ
  • โžค ์„œ๋กœ ๋ฐฐ๋ ค ์—†์ด ๊ธฐ๋‹ค๋ฆฌ๊ธฐ๋งŒ ํ•˜๋ฉด ๊ต์ฐฉ ๊ฐ€๋Šฅ
  • Peterson ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ์ด๊ฑธ ๊ฐœ์„  (flag + turn)

 
 

๐Ÿ“„ Algorithm 2 - Mutual Exclusion (2-Process)

๋‘ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋™์‹œ์— **Critical Section(CS)**์— ๋“ค์–ด๊ฐ€์ง€ ์•Š๋„๋ก ์ƒํ˜ธ๋ฐฐ์ œ(Mutual Exclusion)๋ฅผ ๋ณด์žฅ


๐Ÿ“Œ ์‚ฌ์šฉ ๋ณ€์ˆ˜

c
์ฝ”๋“œ ๋ณต์‚ฌ
boolean flag[2]; // ๊ฐ ํ”„๋กœ์„ธ์Šค์˜ ์˜์‚ฌ ํ‘œํ˜„ (CS ๋“ค์–ด๊ฐ€๊ฒ ๋‹ค๊ณ  ์‹ ํ˜ธ)
  • ์ดˆ๊ธฐ ์ƒํƒœ: flag[0] = flag[1] = false
  • flag[i] = true โ†’ ํ”„๋กœ์„ธ์Šค Pi๋Š” CS ์ง„์ž…์„ ์›ํ•จ
  • flag[j] = true โ†’ ์ƒ๋Œ€ ํ”„๋กœ์„ธ์Šค๊ฐ€ CS์— ๋“ค์–ด๊ฐ€๋ ค๊ณ  ํ•œ๋‹ค๊ณ  ์ธ์‹๋จ

๐Ÿงฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌ์กฐ (P_i ๊ด€์ )

c
์ฝ”๋“œ ๋ณต์‚ฌ
do { flag[i] = true; // CS์— ๋“ค์–ด๊ฐ€๊ฒ ๋‹ค๊ณ  ์„ ์–ธ while (flag[j]); // ์ƒ๋Œ€๊ฐ€ CS์— ๋“ค์–ด๊ฐ€๋ ค๋Š” ์ค‘์ด๋ฉด ๋Œ€๊ธฐ // Critical Section flag[i] = false; // ๋‚˜๊ฐ€๋ฉด์„œ flag ๋‚ด๋ฆผ // Remainder Section } while (1);

๐Ÿ“Ž ์Šฌ๋ผ์ด๋“œ ํ•„๊ธฐ ํ•ด์„

  • flag[i] = true: ๋‚˜ ๋“ค์–ด๊ฐˆ๊ฒŒ
  • while (flag[j]): ์ƒ๋Œ€๋ฐฉ๋„ ๋“ค์–ด๊ฐˆ ๊ฑฐ๋ผ๋ฉด ๊ธฐ๋‹ค๋ ค๋ผ
  • โ— ์„œ๋กœ ๋™์‹œ์— flag[0] = true, flag[1] = true ํ•˜๊ฒŒ ๋˜๋ฉด โ†’ ๋‘˜ ๋‹ค ๊ธฐ๋‹ค๋ฆฌ๋ฉฐ ๋ฌดํ•œ ๋ฃจํ”„ ๊ฐ€๋Šฅ์„ฑ ์กด์žฌ
    (โ†’ progress ๋ณด์žฅ ์‹คํŒจ)

๐Ÿ” ๋งŒ์กฑ ์กฐ๊ฑด ๋ถ„์„

์กฐ๊ฑด๋งŒ์กฑ ์—ฌ๋ถ€์„ค๋ช…
Mutual Exclusion โœ… ๋งŒ์กฑ ๋‘˜ ๋‹ค ๋™์‹œ์— CS ๋ชป ๋“ค์–ด๊ฐ
Progress โŒ ๋ถˆ๋งŒ์กฑ ๋‘˜ ๋‹ค flag = true ์„ค์ • ํ›„ ๋Œ€๊ธฐํ•˜๋ฉด ์ง„์ž… ๋ชปํ•˜๊ณ  ๋ฉˆ์ถค
Bounded Waiting โŒ ๋ถˆ๋งŒ์กฑ ํ•œ ์ชฝ์ด ๊ณ„์† CS ๋“ค์–ด๊ฐ€๋ฉด ๋‹ค๋ฅธ ์ชฝ์€ ๋ฌดํ•œ ๋Œ€๊ธฐ ๊ฐ€๋Šฅ

โ— ํŽ˜ํŠธerson's Algorithm์ด ์™œ ํ•„์š”ํ•œ์ง€ ์•”์‹œ

  • ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ Mutual Exclusion์€ ์ง€ํ‚ค์ง€๋งŒ,
    **์ง„ํ–‰์„ฑ(Progress)**๊ณผ **๊ณต์ •์„ฑ(Bounded Waiting)**์€ ๋ณด์žฅํ•˜์ง€ ๋ชปํ•จ.
  • ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด **Petersonโ€™s Algorithm (Algorithm 3)**๊ฐ€ ๋“ฑ์žฅํ•จ

โœ… ์š”์•ฝ ๋ฌธ์žฅ

Algorithm 2๋Š” ์„œ๋กœ ์–‘๋ณดํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฌดํ•œํžˆ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์žˆ๋‹ค๋Š” ํ•œ๊ณ„๋ฅผ ๊ฐ€์ง€๋ฉฐ,
์ง„์ž… ์ˆœ์„œ๋ฅผ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๋ณ„๋„ ๋ณ€์ˆ˜(turn)๊ฐ€ ์—†์–ด ์ง„ํ–‰์„ฑ์ด ๋ณด์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค.


๐Ÿ’ก ์•”๊ธฐ ํฌ์ธํŠธ

  • flag[i] = true: ๋‚˜ ๋“ค์–ด๊ฐ€๊ณ  ์‹ถ์–ด!
  • while (flag[j]): ์ƒ๋Œ€๊ฐ€ ์›ํ•˜๋ฉด ๊ธฐ๋‹ค๋ ค์•ผ ํ•จ
  • ์„œ๋กœ ๋™์‹œ์— ์ง„์ž… ์˜์‚ฌ๋ฅผ ํ‘œ์‹œํ•  ๊ฒฝ์šฐ ๊ต์ฐฉ ์ƒํƒœ ๋ฐœ์ƒ ๊ฐ€๋Šฅ
  • Mutual Exclusion์€ ์ง€ํ‚ค์ง€๋งŒ, ๋‚˜๋จธ์ง€ ์กฐ๊ฑด์€ ๋ถˆ์ถฉ๋ถ„

 
 
 
 
 

๐Ÿง  Petersonโ€™s Algorithm โ€“ Algorithm 3

๐Ÿ”‘ ํ•ต์‹ฌ ๊ฐœ๋…

  • ๋‘ ๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค(Pโ‚€, Pโ‚) ์‚ฌ์ด์—์„œ Mutual Exclusion, Progress, Bounded Waiting ์กฐ๊ฑด์„ ๋ชจ๋‘ ๋งŒ์กฑํ•˜๋„๋ก ์„ค๊ณ„๋œ ์•Œ๊ณ ๋ฆฌ์ฆ˜.
  • flag[i]: ๋‚˜์˜ ์ง„์ž… ์˜๋„๋ฅผ ๋‚˜ํƒ€๋ƒ„
  • turn: ๋งˆ์ง€๋ง‰์œผ๋กœ ์ง„์ž…์„ ์–‘๋ณดํ•œ ์ชฝ์„ ๊ธฐ์–ต (์ƒ๋Œ€๋ฐฉ์—๊ฒŒ ๊ธฐํšŒ๋ฅผ ์ฃผ๊ธฐ ์œ„ํ•จ)

๐Ÿ“Œ ์‚ฌ์šฉ ๋ณ€์ˆ˜

c
์ฝ”๋“œ ๋ณต์‚ฌ
boolean flag[2] = {false, false}; // ์ฒ˜์Œ์—๋Š” ์•„๋ฌด๋„ CS ์›ํ•˜์ง€ ์•Š์Œ int turn; // ๋งˆ์ง€๋ง‰์œผ๋กœ ์ƒ๋Œ€์—๊ฒŒ ํ„ด์„ ๋„˜๊ธด ์ชฝ

๐Ÿงฑ ํ”„๋กœ์„ธ์Šค Pi ์ฝ”๋“œ

c
์ฝ”๋“œ ๋ณต์‚ฌ
do { flag[i] = true; // CS ์ง„์ž… ์˜์‚ฌ ํ‘œํ˜„ turn = j; // ์ƒ๋Œ€๋ฐฉ์—๊ฒŒ ๋จผ์ € ๊ธฐํšŒ๋ฅผ ์คŒ while (flag[j] && turn == j); // ์ƒ๋Œ€๋„ ์›ํ•˜๊ณ , ์ƒ๋Œ€ ํ„ด์ด๋ฉด ๊ธฐ๋‹ค๋ฆผ // Critical Section ... flag[i] = false; // CS ์ข…๋ฃŒ ํ›„ ์˜์‚ฌ ์ฒ ํšŒ // Remainder Section ... } while (true);

๐Ÿ’ก ์—ฌ๊ธฐ์„œ i๋Š” ์ž๊ธฐ ๋ฒˆํ˜ธ, j๋Š” ์ƒ๋Œ€ ํ”„๋กœ์„ธ์Šค ๋ฒˆํ˜ธ (0 ๋˜๋Š” 1)


โœ… ๋งŒ์กฑ ์กฐ๊ฑด

์กฐ๊ฑด๋งŒ์กฑ ์—ฌ๋ถ€์„ค๋ช…
Mutual Exclusion โœ… ๋งŒ์กฑ ๋™์‹œ์— ๋‘ ํ”„๋กœ์„ธ์Šค๊ฐ€ CS์— ์ง„์ž… ๋ถˆ๊ฐ€
Progress โœ… ๋งŒ์กฑ ์ง„์ž… ์•ˆํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๋Š” ๊ฐ„์„ญ ๋ชป ํ•จ
Bounded Waiting โœ… ๋งŒ์กฑ ์ƒ๋Œ€๋ฐฉ์ด ๊ณ„์† ์ง„์ž…ํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ฐฉ์ง€

๐Ÿ” ํ•„๊ธฐ ์š”์•ฝ ํ•ด์„

  • flag[i] & turn==j ์ด ์กฐ๊ฑด์ด ๋‘ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋™์‹œ์— ๋“ค์–ด๊ฐ€๋Š” ๊ฑธ ๋ง‰์Œ
  • turn์€ ์–‘๋ณดํ•˜๋Š” ๋ณ€์ˆ˜, ๋‘˜ ๋‹ค ์ง„์ž… ์›ํ•˜๋ฉด ์ตœ๊ทผ ์–‘๋ณดํ•œ ํ”„๋กœ์„ธ์Šค๋Š” ๋Œ€๊ธฐ
  • flag๋Š” ๋‚ด๊ฐ€ ์ง„์ž… ์˜์‚ฌ๋ฅผ ํ‘œํ˜„ํ–ˆ๋Š”์ง€ ๋‚˜ํƒ€๋ƒ„
  • ํ•„๊ธฐ ์ค‘:
    • Busy Waiting์€ ์žˆ์Œ (while ์กฐ๊ฑด ๋ฌดํ•œ ํ™•์ธ)
    • mutex + progress + bounded waiting ๋‹ค ๋งŒ์กฑ
    • Peterson์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ 1๊ณผ 2๋ฅผ ์กฐํ•ฉํ•œ ๊ตฌ์กฐ
    • jump table ์ด์Šˆ ํ•ด๊ฒฐ๋จ (๋Œ€๊ธฐ ์ˆœ์„œ ๋ณด์žฅ๋จ)

๐Ÿ’ฌ ์•”๊ธฐ ํฌ์ธํŠธ ์š”์•ฝ

  • flag[i] = true: ๋‚˜๋Š” ๋“ค์–ด๊ฐ€๊ณ  ์‹ถ์–ด!
  • turn = j: ๋„ค๊ฐ€ ๋จผ์ € ๋“ค์–ด๊ฐ€
  • while(flag[j] && turn == j): ๋„ค๊ฐ€ ์›ํ•˜๋ฉด ๋จผ์ € ๋“ค์–ด๊ฐ€
  • flag[i] = false: ๋‚˜ CS ๋๋‚ฌ์–ด
  • โ‡’ ์ด ๊ตฌ์กฐ๊ฐ€ ์„ธ ์กฐ๊ฑด ๋‹ค ๋งŒ์กฑ์‹œํ‚ด

๐Ÿšจ ์ฃผ์˜

  • ๋‘ ๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๋งŒ์„ ์œ„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (n๊ฐœ์— ์ผ๋ฐ˜ํ™”ํ•˜๋ ค๋ฉด Filter Algorithm, Bakery Algorithm ํ•„์š”)