๐Ÿธminzzi
Minzzi์•ผ
๐Ÿธminzzi
์ „์ฒด ๋ฐฉ๋ฌธ์ž
์˜ค๋Š˜
์–ด์ œ
  • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (132)
    • ์˜ค๋ฅ˜ํ•ด๊ฒฐ (14)
    • FE (36)
      • Next.js (17)
      • React (4)
      • React Native (0)
      • TypeScript (1)
      • JavaScript (14)
    • BE (0)
      • Nest.js (0)
    • ๋ฐ๋ธŒ์ฝ”์Šค (7)
    • ์›น ํ”„๋กœ์ ํŠธ (5)
    • CS (28)
      • Algorithm (5)
      • Python (4)
      • C++ (2)
      • Operating System (4)
      • Computer Networking (3)
      • Data Structure (1)
      • Machine Learning (3)
      • Tip (6)
    • Github (4)
    • Flutter (3)
      • ํ”„๋กœ์ ํŠธ (3)
    • Private (3)
      • ํšŒ๊ณ  (7)
      • ๋ฉด์ ‘ (17)
    • ๊ฐœ๋ฐœ๋„์„œ (7)

๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

  • ํ™ˆ

๊ณต์ง€์‚ฌํ•ญ

์ธ๊ธฐ ๊ธ€

ํƒœ๊ทธ

  • ๋ชจ๋˜๋ฆฌ์•กํŠธ๋”ฅ๋‹ค์ด๋ธŒ
  • reflow
  • ํ‹ฐ์Šคํ† ๋ฆฌ์ฑŒ๋ฆฐ์ง€
  • layout shift
  • ์ด๋ฏธ์ง€ ์ตœ์ ํ™”
  • ํ˜ธ์ด์ŠคํŒ…
  • next.js
  • react
  • ์‹คํ–‰์ปจํƒ์ŠคํŠธ
  • ์›์‹œํƒ€์ž…
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ
  • ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…
  • ๋ฉด์ ‘
  • ์ฝœ์Šคํƒ
  • ์˜ค๋ธ”์™„
  • SSR
  • ์‹คํ–‰์ปจํ…์ŠคํŠธ
  • ํž™์˜์—ญ
  • ์ด๋ฒคํŠธ๋ฃจํ”„
  • ๋ ‰์‹œ์ปฌ

์ตœ๊ทผ ๋Œ“๊ธ€

์ตœ๊ทผ ๊ธ€

ํ‹ฐ์Šคํ† ๋ฆฌ

hELLO ยท Designed By ์ •์ƒ์šฐ.
๐Ÿธminzzi
CS/Operating System

[์šด์˜์ฒด์ œ] Chapter6. Synchronization Tools(๋™๊ธฐํ™”)

CS/Operating System

[์šด์˜์ฒด์ œ] Chapter6. Synchronization Tools(๋™๊ธฐํ™”)

2022. 5. 30. 20:33

1.  Background

์ด ์žฅ์—์„œ๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ณ‘ํ–‰ ๋˜๋Š” ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋  ๋•Œ ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ณต์œ ํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ๋ฌด๊ฒฐ์„ฑ์— ์–ด๋–ค ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๋Š” ์ง€์— ๊ด€ํ•ด ์„ค๋ช…ํ•œ๋‹ค. 

Process communication method ์ธ 1)message passing 2)Shared memory๊ฐ€ ์ด๋ฃจ์–ด ์งˆ๋•Œ ์ถฉ๋Œ์ด ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๋‹ค.

 

์˜ˆ) Producer-consumer problem

- ๊ณต์œ ๋ฉ”๋ชจ๋ฆฌ(shared memory)๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ Producer์™€ Consumer์˜ ๊ณผ์ •์ด ์ด๋ฃจ์–ด ์ง€๋ฉด์„œ Buffer๊ฐ€ ์ด์šฉ๋˜๋Š”๋ฐ ์ด๋•Œ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. 

: Concurrent Access of Shared Data(๊ณต์œ ๋ฐ์ดํ„ฐ๋กœ์˜ ๋™์‹œ์ ‘๊ทผ)

์ž์„ธํ•˜๊ฒŒ ์„ค๋ช…์„ ํ•˜์ž๋ฉด, size๊ฐ€ 5์ธ buffer(circular queue)๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•  ๋•Œ, Producer๋Š” counter๋ฅผ 1์”ฉ ์ฆ๊ฐ€์‹œํ‚ค๊ณ , Consumer๋Š” counter๋ฅผ 1์”ฉ ๊ฐ์†Œ์‹œํ‚จ๋‹ค. ์•„๋ž˜ producer์™€ consumer๋Š” ์ด๋ฅผ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ์ด๋‹ค.  

Producer

//Producer
While(true){
while(counter == BUFFER_SIZE); //true = ๋ฒ„ํผ๊ฐ€ ๊ฝ‰์ฐธ / false = ๋ฒ„ํผ ๊ณต๊ฐ„ ์žˆ์Œ, ๋‹ค์Œ์ค„๋กœ
buffer[in] = nextProduced;
in = (in + 1) % BUFFERSIZE;
counter++;
}

producer๋Š” buffer์ž…์žฅ์—์„œ ์ƒ์‹œ๋Œ€๊ธฐ๋กœ buffer์— ์ฑ„์šธ ์ˆ˜ ์žˆ๋Š” ๊ณต๊ฐ„์ด ์žˆ๋‹ค๋ฉด(๋ฒ„ํผ๊ฐ€ ๋น„์–ด์žˆ๋‹ค๋ฉด) ๋ฒ„ํผ๋ฅผ ์ฑ„์šฐ๊ณ  counter๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

Consumer

//Consemer
while(true){
while(counter == 0);//true = ๋ฒ„ํผ ๋น” / false = ๋ฒ„ํผ ๋น„์–ด์žˆ์ง€ ์•Š์Œ
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
}

consumer๋Š” producer์™€ ์™„์ „ํžˆ ๋ฐ˜๋Œ€๋กœ ๋Œ์•„๊ฐ„๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. 

ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค!

  • Synchronization Problem

๋จผ์ € producer๊ฐ€ ๋จผ์ € ์‹คํ–‰๋œ ์ƒํƒœ์—์„œ๋ถ€ํ„ฐ ์ƒํ™ฉ์„ ์‚ดํŽด๋ณด์ž.

๊ทธ ์ „์— counter๋ผ๋Š” ๋ณ€์ˆ˜์˜ ๊ฐ’์ด ์–ด๋–ค ๊ณผ์ •์„ ๊ฑฐ์ณ ์ฆ๊ฐ€ํ•˜๊ณ  ๊ฐ์†Œํ•˜๋Š” ์ง€ ๊ฐ„๋žตํžˆ ๋ณด์ž.

- counter++์˜ ๊ณผ์ •

//counter์˜ ๊ฐ’์ด ๋ ˆ์ง€์Šคํ„ฐ์— ์ €์žฅ๋˜๊ณ  ์ฆ๊ฐ€๋œ ๋ ˆ์ง€์Šคํ„ฐ์˜ ๊ฐ’์„ counter์— ๋‹ค์‹œ ์ €์žฅ์‹œํ‚ค๋Š” ๊ณผ์ •์œผ๋กœ ์ง„ํ–‰๋œ๋‹ค.
register_1 = counter
register_1 = register_1 + 1
counter = register_1

 - counter--์˜ ๊ณผ์ •

register_2 = counter
register_2 = register_1 - 1
counter = register_2

[Normal situation]

- counter์˜ ๊ธฐ์กด ๊ฐ’์€ 5

- producer์™€ consumer๊ฐ€ ๋™์‹œ์— ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚ค๊ณ  ๊ฐ์†Œ์‹œํ‚ค๋Š” ์ƒํ™ฉ

- ์ด์ƒ์ ์œผ๋กœ๋Š” counter๊ฐ€ 5๊ฐ€ ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ์ด ๊ฐ„๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค. 

Producer Consumer
register_1 = counter (register_1 = 5)  
register_1 = register_1 + 1 (register_1 = 6)
  register_2 = counter (register_2 = 5)
register_2 = register_2 - 1 (register_2 = 4)
counter = register_1 (counter = 6)  
  counter = register_2 (counter = 4)

synchronization problem ๊ณผ์ •

  • counter์˜ ๊ฐ’์ด 5์ด๊ธฐ ๋•Œ๋ฌธ์— producer์™€ consumer๋ชจ๋‘ counter์˜ ๊ฐ’์„ 5๋กœ ๋ฐ›์•„์˜จ๋‹ค. ๊ทธ๋ž˜์„œ register_1, register_2์—๋Š” ๊ฐ๊ฐ 5๊ฐ€ ์ €์žฅ์ด ๋œ๋‹ค.
  • producer์™€ consumer๋Š” ๊ฐ๊ฐ register์˜ ๊ฐ’์„ 1 ์ฆ๊ฐ€์‹œํ‚ค๊ณ  ๊ฐ์†Œ์‹œํ‚จ๋‹ค. 
  • register์˜ ๊ฐ’์„ counter์— ์ €์žฅํ•˜๋Š” ๊ณผ์ •์—์„œ producer์€ 6์˜ ๊ฐ’์„ ๋ฐ›๊ณ , consumer์—์„œ๋Š” 4์˜ ๊ฐ’์„ ๋ฐ›์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ  ์ด๋•Œ problem์ด ๋ฐœ์ƒํ•œ๋‹ค. 

๋”ฐ๋ผ์„œ, 

์ด์ฒ˜๋Ÿผ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์–ด๋–ค ์ˆœ์„œ๋กœ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋А๋ƒ์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ ๊ฐ’์ด ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์„ Race condition(๊ฒฝ์Ÿ ์ƒํƒœ)๋ผ๊ณ  ํ•œ๋‹ค. 

 

race condition์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ synchronization์ด ๋˜์–ด์ ธ์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. 


2. The Critical-Section Problem

ํ”„๋กœ์„ธ์Šค ๋™๊ธฐํ™”์— ๋Œ€ํ•œ ๋ฌธ์ œ๋Š” critical section problem์ด๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ๋ฌธ์ œ๋กœ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค.

์—ฌ๊ธฐ์— n๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค {p0, p1, ..., p(n-2)}๊ฐ€ ์กด์žฌํ•œ๋‹ค๊ณ  ํ•˜์ž.

 

๊ทธ ์ „์— critical section์ด๋ž€?

- ์ฝ”๋“œ์—์„œ race condition์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ํŠน์ • ๋ถ€๋ถ„์„ critical section์ด๋ผ๊ณ  ํ•œ๋‹ค. 

- critical section์ด ์‚ฌ์šฉ๋˜๋Š” ์‹œ์Šคํ…œ์—์„œ๋Š” ํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž์‹ ์˜ ์ž„๊ณ„๊ตฌ์—ญ์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ๋™์•ˆ์— ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์„œ๋“ค์€ ๊ทธ๋“ค์˜ ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์—†๋‹ค.

 

์ฆ‰, critical-section problem์ด๋ž€ ํ”„๋กœ์„ธ์„œ๋“ค์ด ๋ฐ์ดํ„ฐ๋ฅผ ํ˜‘๋ ฅ์ ์œผ๋กœ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ์ž์‹ ๋“ค์˜ ํ™œ๋™์„ ๋™๊ธฐํ™”ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ์ฝ”ํ†จ(์•ฝ์†)์„ ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

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

์ด๋ฅผ ์ฝ”๋“œ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

do{
entry section
critical section
exit section
remainder section
}while(true);

๊ฐ ํ”„๋กœ์„ธ์„œ์—์„œ critical section์˜ ๋ฐ์ดํ„ฐ๋Š” shared data์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

Critical Section Problem์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„  ๋ช‡๊ฐ€์ง€ ์กฐ๊ฑด์„ ์ถฉ์กฑํ•ด์•ผ ํ•œ๋‹ค.

  • Mutual Excludion(์ƒํ˜ธ ๋ฐฐ์žฌ) : ์ด๋ฏธ ํ•œ process๊ฐ€ critical section์—์„œ ์ž‘์—…์ค‘์ด๋ฉด ๋‹ค๋ฅธ process๋Š” critical section์— ์ง„์ž…ํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค.
  • Progress(์ง„ํ–‰) : critical section์—์„œ ์ž‘์—…์ค‘์ธ process๊ฐ€ ์—†๋‹ค๋ฉด ๋‹ค๋ฅธ process๊ฐ€ critical section์— ์ง„์ž…ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. 
  • Bounded Waiting(ํ•œ์ • ๋Œ€๊ธฐ) : critical section์— ์ง„์ž…ํ•˜๋ ค๋Š” process๊ฐ€ ๋ฌดํ•œํ•˜๊ฒŒ ๋Œ€๊ธฐํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค.

Critical-section Handling in OS

- pid๋ฅผ ํ• ๋‹นํ•  ๋•Œ race condition์˜ ์˜ˆ

  • ํ”„๋กœ์„ธ์Šค p0์™€ p1์ด ๋™์‹œ์— fork()๋ฅผ ์ด์šฉํ•˜์—ฌ child processes๋ฅผ ๋งŒ๋“ค๋ ค๊ณ  ํ•œ๋‹ค.
  • ๋‹ค์Œ์œผ๋กœ ์ด์šฉ๊ฐ€๋Šฅํ•œ process์˜ id(pid)๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” 'next_available_pid' ๋ณ€์ˆ˜์—์„œ race condition์ด ์ผ์–ด๋‚œ๋‹ค. 
  • ๋งŒ์ผ mutual exclusion(์ƒํ˜ธ ๋ฐฐ์žฌ)๊ฐ€ ์—†๋‹ค๋ฉด ๊ฐ™์€ pid๊ฐ€ ๋‘๊ฐœ์˜ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์— ๋ฐฐ์ •๋  ์ˆ˜ ์žˆ๋‹ค. 

- ์šด์˜์ฒด์ œ ๋‚ด์—์„œ critical section์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด Preemptive kernels๊ณผ Non-preemptive kernels์˜ ๋‘๊ฐ€์ง€ ์ผ๋ฐ˜์ ์ธ ์ ‘๊ทผ๋ฒ•์ด ์‚ฌ์šฉ๋œ๋‹ค. 

  • preemptive kernels(์šฐ์„ ์ˆœ์œ„ ๋†’์€๊ฑฐ) 
    • ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ปค๋„ ๋ชจ๋“œ์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ๋™์•ˆ ์„ ์ ๋˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•œ๋‹ค.
    • ์„ ์ ํ˜• ์ปค๋„์— ๋Œ€ํ•ด์„œ๋Š” ๋™์ผํ•œ ์ฃผ์žฅ์„ ํ•  ์ˆ˜ ์—†์–ด race condition์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ณต์œ ๋˜๋Š” ์ปค๋„ ์ž๋ฃŒ๊ตฌ์กฐ์—์„œ race condition์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๋„๋ก ์‹ ์ค‘ํ•˜๊ฒŒ ์„ค๊ณ„๋˜์–ด์•ผ ํ•œ๋‹ค. 
  • Non-preemptive kernels
    • ์ปค๋„ ๋ชจ๋“œ์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ํ”„๋กœ์„ธ์Šค์˜ ์„ ์ ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ณ  ์ปค๋„ ๋ชจ๋“œ ํ”„๋กœ์„ธ์Šค๋Š” ์ปค๋„์„ ๋น ์ ธ๋‚˜๊ฐˆ ๋•Œ๊นŒ์ง€ ๋˜๋Š” ๋ด‰์‡„๋  ๋•Œ๊นŒ์ง€ ๋˜๋Š” ์ž๋ฐœ์ ์œผ๋กœ CPU์˜ ์ œ์–ด๋ฅผ ์–‘๋ณดํ•  ๋•Œ๊นŒ์ง€ ๊ณ„์† ์ˆ˜ํ–‰๋œ๋‹ค. 
    • ํ•œ ์ˆœ๊ฐ„์— ์ปค๋„ ์•ˆ์—์„œ ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋Š” ํ•˜๋‚˜๋ฐ–์— ์—†์œผ๋ฏ€๋กœ race condition์„ ์—ผ๋ คํ•  ํ•„์š”๋Š” ์—†๋‹ค. 

์ปค๋„๋ชจ๋“œ ํ”„๋กœ์„ธ์„œ๊ฐ€ ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์„œ๋ฅผ ์–‘๋„ํ•˜๊ธฐ ์ „์— ์˜ค๋žซ๋™์•ˆ ์‹คํ–‰ํ•  ์œ„ํ—˜์ด ์ ๊ธฐ ๋•Œ๋ฌธ์— ์„ ์ ํ˜• ์ปค๋„์€ ๋” ์‘๋‹ต์ด ๋ฏผ์ฒฉํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์„ ์ ํ˜• ์ปค๋„์„ ์„ค๊ณ„ํ•˜๊ธฐ ์•ž์„œ ๊ฒฝ์Ÿ ์กฐ๊ฑด์„ ์ž˜ ๊ณ ๋ คํ•ด์•ผ๋งŒ ํ•œ๋‹ค. 


3. Peterson's Solution

Peterson's Solution์ด๋ž€ critical-section problem์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•œ ๊ณ ์ „์ ์ธ ์†Œํ”„ํŠธ์›จ์–ด ๊ธฐ๋ฐ˜ ํ•ด๊ฒฐ์ฑ…์ด๋‹ค.

  • modern architecture์—๋Š” ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š”์ง€๋Š” ๋ณด์žฅ๋˜์ง€ ์•Š์Œ
  • ํ•˜์ง€๋งŒ ๊ทธ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ์—๋Š” ์ข‹์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์„ค๋ช…์ด๋‹ค.
  • Critical section๊ณผ Remainder section์„ ๋ฒˆ๊ฐˆ์•„ ๊ฐ€๋ฉฐ ์‹คํ–‰ํ•˜๋Š” ๋‘๊ฐœ์˜ ํ”„๋กœ์„ธ์„œ(pi, pj)๋กœ ํ•œ์ •๋œ๋‹ค.
  • load์™€ store machine language ๋ช…๋ น์–ด๊ฐ€ atomicํ•˜๋‹ค. ์ฆ‰ ๋‘ ๋ช…๋ น์–ด๋Š” ์‹คํ–‰์ค‘์— ์ค‘๋‹จํ•˜์ง€ ์•Š๋Š”๋‹ค(interrupt ๋˜์ง€ ์•Š๋Š”๋‹ค.)
  • ๋‘ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋‘ ๊ฐœ์˜ ๋ฐ์ดํ„ฐ ํ•ญ๋ชฉ์„ ๊ณต์œ ํ•˜๋„๋ก ํ•˜์—ฌ ํ•ด๊ฒฐํ•œ๋‹ค. 
    • int turn; //critical section์œผ๋กœ ์ง„์ž…ํ•  ์ˆœ๋ฒˆ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ณ€์ˆ˜
    • boolean falg[2]; // ๊ฐ ํ”„๋กœ์„ธ์„œ๊ฐ€ critical section์œผ๋กœ ์ง„์ž…ํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ํ‘œํ˜„ํ•œ ๋ฐฐ์—ด

Pi์˜ Peterson ์•Œ๊ณ ๋ฆฌ์ฆ˜

int turn;
boolean flag[2]; //flag[i] == true -> pi ์ค€๋น„๋๋‹ค!
...
while(true){
flag[i] = true;
turn = j;
while(falg[j] && turn == j);
/* critical section */
flag[i] = false;
/* remainder section */
}

peterson's solution์˜ ๊ณผ์ •(์ƒํƒœ)

p0, p1์˜ ํ”„๋กœ์„ธ์„œ๋“ค์ด ์กด์žฌํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž.

  1. p0๊ฐ€ ๋จผ์ € ์‹œ์ž‘
    • flag[0] = true
    • turn = 1
  2. ๊ทธ ๋’ค๋กœ ๋ฐ”๋กœ p1๋„ ์‹œ์ž‘
    • flag[0] = true
    • flag[1] = true
    • turn  = 1 -> 0
  3. p0 critical section ์ง„์ž… ( while(flag[1] && turn == 1); -> false)
    • flag[0] = true -> false
    • flag[1] = true
    • turn = 0
  4. p1 critical section ์ง„์ž…( while(flag[0] && turn == 0); -> false)
    • flag[0] = false
    • flag[1] = false
    • turn = 0
  5. p0 ์ž…์žฅ์—์„œ critical section ๋‹ค์Œ์œผ๋กœ while๋ฌธ์„ ๋˜ ๋Œ๊ณ  ์žˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ 4๋ฒˆ์—์„œ flag[1] = false๊ฐ€ ๋์œผ๋ฏ€๋กœ p0์€ critical section์ง„์ž… ๊ฐ€๋Šฅ
    • flag[0] = true-> false(CS ์ง„์ž…์ดํ›„)  
    • flag[1] = false
    • turn = 1
    • p1์—์„œ๋„ turn = 0์œผ๋กœ ๋ฐ”๊พธ๋ฏ€๋กœ p0์ดํ›„๋กœ critical section ์ง„์ž… ๊ฐ€๋Šฅ, ๊ณ„์† ๋ฐ˜๋ณต์  -> atomic

Proof of Peterson's Solution

peterson's solution์ด critical section ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„  3๊ฐ€์ง€ ์š”๊ตฌ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผ ํ•œ๋‹ค. 

  1. Mutual Exclusion(์ƒํ˜ธ๋ฐฐ์žฌ)
    • ๋งŒ์•ฝ pi์™€ pj๊ฐ€ ๋‘˜๋‹ค critical section์— ๋“ค์–ด๊ฐ”๋‹ค๋ฉด,
    • flag[0] = flag[1] = true ์ผ์ˆ˜๋ฐ–์— ์—†๊ณ 
    • turn๋„ 0, 1๋‘˜๋‹ค ํ•ด๋‹น๋˜์–ด์ ธ์•ผ๋งŒ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ turn์€ ๊ทธ๋Ÿด ์ˆ˜ ์—†๋‹ค. 
    • ๊ทธ๋Ÿฌ๋ฏ€๋กœ mutual exclusion์€ ๋งŒ์กฑํ•œ๋‹ค.
  2. Progress(์ง„ํ–‰) & Bounded waiting(ํ•œ์ • ๋Œ€๊ธฐ)
    • pi์˜ blocking condition : while(flag[j] && turn == j);
      • ๋งŒ์•ฝ pj๊ฐ€ ์•„์ง critical section์— ๋“ค์–ด๊ฐˆ ์ค€๋น„๊ฐ€ ์•ˆ๋๋‹ค๋ฉด : flag[j] = false; -> pi๋Š” critical section์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ์Œ!
      • ๋งŒ์•ฝ pj๊ฐ€ while๋ฌธ์—์„œ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๊ณ , turn์€ i, j ๋‘˜ ๋‹ค ๊ฐ€๋Šฅ์ผ๋•Œ
      • ๋งŒ์•ฝ turn = i๊ฐ€ ๋œ๋‹ค๋ฉด pi๋Š” critical section์— ๋“ค์–ด๊ฐ
      • ๋งŒ์•ฝ turn = j๊ฐ€ ๋œ๋‹ค๋ฉด pj๋Š” critical section ์— ๋“ค์–ด๊ฐ
        • pj๊ฐ€ critical section์„ ๋๋‚ธ๋‹ค๋ฉด pj๋Š” flag[j] = false๋กœ ๋งŒ๋“ ๋‹ค. ๊ทธ๋ฆฌ๊ณ  pi๋Š” critical section์œผ๋กœ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. pj๊ฐ€ turn์„ i๋กœ ๋ฐ”๊ฟจ๊ธฐ ๋•Œ๋ฌธ!
    • ๊ทธ๋Ÿฌ๋ฏ€๋กœ pi๋Š” critical section์œผ๋กœ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๊ณ (progress), ๊ทธ์ € ํ•˜๋‚˜์˜ process๋งŒ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋œ๋‹ค (bounded waiting)

Peterson's solution์€ ์ตœ์‹  ์ปดํ“จํ„ฐ๊ตฌ์กฐ์—์„œ๋Š” ์ž‘๋™ํ•œ๋‹ค๊ณ  ๋ณด์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค. ์ฃผ๋œ ์ด์œ ๋Š” ์‹œ์Šคํ…œ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœ์„ธ์Šค ๋˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ข…์†์„ฑ์ด ์—†๋Š” ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ ์ž‘์—…์„ ์žฌ์ •๋ ฌ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์˜ˆ๋กœ ๋“ค์–ด, Peterson ํ•ด๊ฒฐ์•ˆ์˜ entry section์˜ ์ฒซ ๋‘ ๋ฌธ์žฅ์˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊พธ๊ฒŒ ๋˜๋ฉด(์•„๋ž˜ ์˜ˆ์‹œ) critical solution์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์—†๋‹ค.

 

entry section์—์„œ์˜ ์ฒซ ๋‘๋ฌธ์žฅ์˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊ฟจ์„ ๋•Œ ์˜ˆ์‹œ

  • ๋‘ ๊ฐœ์˜ thread๊ฐ€ ๊ณต์œ ํ•˜๋Š” ๋ฐ์ดํ„ฐ
    • boolean flag = false;
    • int x = 0;
  • Thread1
    • while(!flag);
    • print x;
  • Thread2
    • x = 100;
    • flag = true;
  • ์˜ˆ์ƒ๋˜๋Š” output
    • 100์ด ์ถœ๋ ฅ ๋  ๊ฒƒ์ž„.
    • ํ•˜์ง€๋งŒ ๋งŒ์•ฝ Thread2์—์„œ ๋‘ ์ค„์˜ ์œ„์น˜๋ฅผ ์„œ๋กœ ๋ฐ”๊พผ๋‹ค๋ฉด? -> output = 0

์ด ์˜ˆ์‹œ๊ฐ€ peterson's solution์œผ๋กœ ์ ์šฉ๋œ๋‹ค๋ฉด?


4. Hardware Support for Synchronization

Critical Section Problem์˜ ์†Œํ”„ํŠธ์›จ์–ด ๊ธฐ๋ฐ˜ ํ•ด๊ฒฐ์ฑ…(peterson's solution)์€ ์ตœ์‹  ์ปดํ“จํ„ฐ๊ตฌ์กฐ์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. 

๊ทธ๋ž˜์„œ hardware์˜ ์ง€์›์ด ํ•„์š”ํ•œ๋ฐ, 4์ ˆ์—์„œ๋Š” Critical section problem์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์ž์›์„ ์ œ๊ณตํ•˜๋Š” ์„ธ ๊ฐ€์ง€ ํ•˜๋“œ์›จ์–ด ๋ช…๋ น(hardware support)์„ ์ œ์‹œํ•œ๋‹ค. 

  • Memory barriers
  • Hardware instructions
  • Atomic variables

1) Memory Barriers(๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ)

: ์ปดํ“จํ„ฐ๊ตฌ์กฐ๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋‹ค๋ฅธ ๋ชจ๋“  ํ”„๋กœ์„ธ์„œ๋กœ ์ „ํŒŒํ•˜๋Š” ๋ช…๋ น์–ด๋ฅผ ์ œ๊ณตํ•˜์—ฌ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์„œ์—์„œ ์‹คํ–‰ ์ค‘์ธ ์Šค๋ ˆ๋“œ์— ๋ฉ”๋ชจ๋ฆฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋ณด์ด๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ๋ช…๋ น์–ด๋ฅผ ๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ(Memory Barriers) ๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ํŽœ์Šค(Memory Fences)๋ผ๊ณ  ํ•œ๋‹ค. 

  • ๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋  ๋•Œ, ์‹œ์Šคํ…œ์€ ํ›„์† load ๋˜๋Š” store ์—ฐ์‚ฐ์ด ์ˆ˜ํ–‰๋˜๊ธฐ ์ „์— ๋ชจ๋“  load ๋ฐ store ์—ฐ์‚ฐ์ด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์™„๋ฃŒ๋˜๋„๋ก ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ช…๋ น์ด ์žฌ์ •๋ ฌ ๋˜๋”๋ผ๋„ ๋ฉ”๋ชจ๋ฆฌ ์žฅ๋ฒฝ์€ future load ๋˜๋Š” store ์ž‘์—…์ด ์ˆ˜ํ–‰๋˜๊ธฐ ์ „์— ์ €์žฅ ์ž‘์—…์ด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์™„๋ฃŒ๋˜์–ด ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์„œ์— ๋ณด์ด๋„๋ก ํ•œ๋‹ค. 
  • ์ด ์ž‘์—…์€ ๋งค์šฐ low-level(๋‚ฎ์€ ์ˆ˜์ค€)์˜ ์ž‘์—…์ด๋‹ค.
  • ์ผ๋ฐ˜์ ์œผ๋กœ Mutual Exclusion์„ ๋ณด์žฅํ•˜๋Š” ํŠน์ˆ˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ์ปค๋„ ๊ฐœ๋ฐœ์ž๋งŒ ์‚ฌ์šฉํ•œ๋‹ค. 

์˜ˆ์‹œ)

์œ„์— ๋‚˜์™”๋˜ x = 100์„ ์ถœ๋ ฅํ•˜๋Š” ์˜ˆ์‹œ๋ฅผ ๊ฐ€์ ธ์™€๋ณด์ž

//Thread1
//x ์ „์— flag๊ฐ€ load ๋˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•จ
while(!flag)
memory_barrier();
print x;
//Thread2
//x ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ensure. flag๊ฐ€ assign ๋˜๊ธฐ ์ „์—
x = 100;
memory_barrier();
flag = true;

memory_barrier();์„ ํ•ด์คŒ์œผ๋กœ์จ x์™€ flag๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•œ๋‹ค.

//Peterson's solution
while(true){
flag[i] = true;
memory_barrier();
turn = j;
while(flag[j] && turn == j);
...
}

 

2) Hardware Instructions

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

  • Test-and-Set instruction
  • Compare-and-Swap instruction

Test-and-Set instruction

//Definition
boolean test_and_set(boolean *target){
boolean rv = *target;
*target = true;
return rv;
}
  • ๊ณ„์†์ ์œผ๋กœ(atomically) ์‹คํ–‰๋œ๋‹ค.
  • ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ธฐ์กด ๊ฐ’(original value)์„ returnํ•œ๋‹ค.
  • ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ฐ’์— ์ƒˆ ๊ฐ’์„ ์„ค์ •ํ•œ๋‹ค.

์ด๋ฅผ ํ™œ์šฉํ•œ Critical Section์˜ Mutual Exclusion ํ•ด๊ฒฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

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

๋งŒ์•ฝ process๊ฐ€ ๋‘๊ฐœ(p0, p1)๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•˜์ž.

๊ธฐ์กด์˜ lock์ด false์ด๋ฉด, p0๋Š” false๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์•„ critical section์œผ๋กœ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œ lock์˜ ๊ฐ’์€ true๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์œผ๋‹ˆ p1์€ ๊ณ„์† while์— ๊ฐ‡ํ˜€์žˆ๊ฒŒ ๋œ๋‹ค. p0์—์„œ critical section์œผ๋กœ ๋“ค์–ด๊ฐ”๋‹ค๋ฉด lock์€ false๋กœ ๋ฐ”๋€Œ๋ฉด์„œ p1์˜ while์กฐ๊ฑด์ธ test_and_set์˜ ๋ฐ˜ํ™˜์ด false๊ฐ€ ๋˜์–ด p1์€ critical section์œผ๋กœ ๋“ค์–ด๊ฐ„๋‹ค. ์ด๋•Œ lock์€ ๋˜ true๋กœ ๋ฐ”๋€Œ๋ฏ€๋กœ p0์€ while๋ฌธ์— ๊ฐ‡ํžˆ๊ฒŒ ๋œ๋‹ค. ์ด๋ ‡๋“ฏ p0์™€ p1์ด ์™”๋‹ค๊ฐ”๋‹ค ๊ณ„์†์ ์œผ๋กœ ๋ฐ˜๋ณตํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

Compare-and-Swap instruction

//Definition
int compare_and_swap(int *value, int expected, int new_value){
int temp = *value;
if (*value == expected)
*value = new_value;
return temp;
}
  • ๋˜ํ•œ atomicalํ•˜๊ฒŒ ์ž‘๋™๋œ๋‹ค.
  • ์ „๋‹ฌ๋œ ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐ’์˜ ๊ธฐ์กด ๊ฐ’(original value)๋ฅผ return ํ•œ๋‹ค. 
  • ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ฐ’์€ new_value๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Š” *value == expected ๊ฐ€ true์ผ๋•Œ๋งŒ ์‹คํ–‰ํ•˜๋„๋ก ํ•œ๋‹ค. 

์ด๋ฅผ ํ™œ์šฉํ•œ Critical Section์˜ Mutual Exclusion ํ•ด๊ฒฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

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

์—ญ์‹œ๋‚˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ p0, p1 ๋‘๊ฐœ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•˜์ž

์›๋ž˜ lock = 0์ด๋ผ๊ณ  ํ•˜๊ณ  ์‹œ์ž‘ํ•˜์ž. p0์ด ๋จผ์ € compare_and_swap์„ ์‹คํ–‰ํ•˜๋ฉด ๊ธฐ์กด๊ฐ’์ด๋˜ 0์„ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ while๋ฌธ ์กฐ๊ฑด์€ false๊ฐ€ ๋˜์–ด critical section์œผ๋กœ ๋“ค์–ด๊ฐ„๋‹ค. p1 ์ž…์žฅ์—์„œ ๋ณด๋ฉด lock์€ 1๋กœ ๋ฐ”๊ผˆ์œผ๋‹ˆ compare_and_swap์ด 1์„ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ์กฐ๊ฑด์€ true๊ฐ€ ๋˜์–ด critical section์œผ๋กœ ๋“ค์–ด๊ฐ€์ง€ ๋ชปํ•œ๋‹ค. ํ•˜์ง€๋งŒ p0๊ฐ€ critical section์—์„œ lock=0์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด ๊ทธ๋•Œ p1์€ compare_and_swap์ด 0์„ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์กฐ๊ฑด์ด false๊ฐ€ ๋˜๊ณ  critical section์œผ๋กœ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ผ์ด ๋ฐ˜๋ณต์ ์œผ๋กœ ์ˆ˜ํ–‰๋œ๋‹ค. 

 

์ด๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

ํ•˜์ง€๋งŒ, ์œ„์˜ ์˜ˆ์‹œ๋Š” bounded waiting ์š”๊ตฌ๋ฅผ ์ถฉ์กฑํ•˜์ง€ ๋ชปํ•œ๋‹ค. 

์ด์œ ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

Bounded waiting mutual exclusion์„ ๋งŒ์กฑํ•˜๊ธฐ ์œ„ํ•ด์„  ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๋กœ ์ž‘์„ฑ์ด ๋˜์–ด์•ผ ํ•œ๋‹ค. 

boolean waiting[n]; //n = process๊ฐœ์ˆ˜, initialized to false
int lock; //initialized to 0
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 */
}

pi๊ฐ€ critical section์— ์ง„์ž…ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์˜ค์ง waiting[i] == false ์ด๋“ ์ง€ key == 0 ์ด ๋˜์–ด์•ผ ํ•œ๋‹ค. lock์ด 0์ผ ๋•Œ์—๋งŒ key๊ฐ€ 0์ด ๋˜๊ณ  lock ์ด 1๋กœ ๋ฐ”๋€Œ๋ฉด์„œ ๋ฌดํ•œ ๋ฃจํ”„์—์„œ ๋น ์ ธ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋‹ค. 

 

waiting[i]๋ฅผ false๋กœ ๋ฐ”๊พธ๊ณ  critical section์„ ์‹คํ–‰ํ•œ ๋’ค, i๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฆ๊ฐ€์‹œ์ผœ ์ž์‹ ๊ณผ ๊ฐ™์„ ๋•Œ๊นŒ์ง€ ํ˜น์€ i๊ฐ€ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์„ ๋•Œ๊นŒ์ง€ ๋ฌดํ•œ ๋ฃจํ”„๋ฅผ ๋Œ๊ณ , ์„ ํƒ๋œ ํ”„๋กœ์„ธ์Šค๋ฅผ critical section์— ์ง„์ž…ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. 

 

3) Atomic Variables

Atomic Variable์€ integers ๋ฐ booleans๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ ์œ ํ˜•์— ๋Œ€ํ•œ Atomic ์—ฐ์‚ฐ์„ ์ œ๊ณตํ•œ๋‹ค. Atomic Variable์€ ์นด์šดํ„ฐ๊ฐ€ ์ฆ๊ฐ€ํ•  ๋•Œ์™€ ๊ฐ™์ด ๊ฐฑ์‹ ๋˜๋Š” ๋™์•ˆ ๋‹จ์ผ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ ๊ฒฝ์Ÿ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์—์„œ ์ƒํ˜ธ ๋ฐฐ์ œ๋ฅผ ๋ณด์žฅํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. 

 

์˜ˆ)

//increment function
void increment(atomic_int *v){
int temp;
do{
temp = *v;
}while(temp != compare_and_swap(v, temp, temp+1));
}
//p1 : temp = 10, *v = 11
//p2 : temp = 10, *v = 12

5. Mutex Locks

Mutex lock์€ mutual exclusion lock์˜ ์ถ•์•ฝํ˜•ํƒœ๋กœ Critical section ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ Hardware๊ธฐ๋ฐ˜์˜ ํ•ด๊ฒฐ์ฑ…(ex.Peterson's solution)๋ณด๋‹ค ์ƒ์œ„ ์ˆ˜์ค€์˜ ํ•ด๊ฒฐ์ฑ…์ด๋‹ค. Critical Section์„ ๋ณดํ˜ธํ•˜๊ณ , ๋”ฐ๋ผ์„œ Race condition์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œˆํ•ด์„œ mutex lock์„ ์‚ฌ์šฉํ•œ๋‹ค. 

 

Mutex lock์—์„œ๋Š” ์„ธ๊ฐ€์ง€๋ฅผ ์•Œ์•„์•ผ ํ•œ๋‹ค. 

  1. acquire(): lock์„ ํš๋“ํ•˜๋Š” ํ•จ์ˆ˜
  2. release(): lock์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
  3. available: lock์˜ ๊ฐ€์šฉ ์—ฌ๋ถ€๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ณ€์ˆ˜

acquireํ•จ์ˆ˜์™€ releaseํ•จ์ˆ˜๋Š” ๋ฐ˜๋“œ์‹œ atomicํ•˜๊ฒŒ ์ž‘๋™๋˜์–ด์•ผ ํ•œ๋‹ค. 

//acquire ํ•จ์ˆ˜
acquire(){
/* busy waiting */
while(!available);
available = false;
}
//release ํ•จ์ˆ˜
release(){
available = true;
}

mutex lock์„ ์‚ฌ์šฉํ•˜์—ฌ critical section problem์„ ํ•ด๊ฒฐํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

while(true){
acquire lock
critical section
release lock
remainder section
}

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

 

์ด๋Ÿฌํ•œ busy waiting์„ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋Š” mutex lock๊ณผ ๊ฐ™์€ ์œ ํ˜•์€ spinlock(์Šคํ•€๋ฝ)์ด๋ผ๊ณ  ๋ถˆ๋ฆฌ๊ธฐ๋„ ํ•œ๋‹ค. 


6. Semaphores

Semaphores ์—ญ์‹œ ๋™๊ธฐํ™” ํˆด์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ Semaphores์€ Mutex lock๋ณด๋‹ค ๋” ์„ธ๋ จ๋œ ๋ฐฉ๋ฒ•์ด๋‹ค. ์„ธ๋งˆํฌ๋Š” ์นด์šดํ„ฐ๋ฅผ ์ด์šฉํ•ด ๋™์‹œ์— ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ์ œํ•œํ•œ๋‹ค. ์„ธ๋งˆํฌ๋Š” P์™€ V๋ผ๋Š” ๋ช…๋ น์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

 

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

 

wait()๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค. 

wait(S){
while(S <= 0); //waits for the lock
S--; // holds the lock
}

signal()๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

signal(S){
S++; // release the lock
}

 

1) Semaphores Usage

์šด์˜์ฒด์ œ๋Š” Counting๊ณผ binary ์„ธ๋งˆํฌ๋ฅผ ๊ตฌ๋ถ„ํ•œ๋‹ค.

  • Counting Semaphores
    • Interger value S๋Š” ์ œํ•œ์—†๋Š” ๊ฐ’์„ ๊ฐ€์ง
    • ์œ ํ•œํ•œ ๊ฐœ์ˆ˜๋ฅผ ๊ฐ€์ง„ ์ž์›(๊ฐ€๋Šฅํ•œ ์ž์›์˜ ๊ฐœ์ˆ˜๋กœ ์ดˆ๊ธฐํ™” ๋จ)์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ œ์–ดํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. 
  • Binary Semaphores
    • Integer value๋Š” 0๊ณผ 1 ์ค‘์—๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.
    • mutex lock๊ณผ ๋น„์Šทํ•˜๋‹ค. 

2) Semaphore Implememtation

์œ„ wait()์˜ while์€ spinlock์œผ๋กœ busy waiting์ด ์ผ์–ด๋‚œ๋‹ค. ์ด๋Ÿฌํ•œ busy waiting์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์„ธ๋งˆํฌ S๋ฅผ ๋Œ€๊ธฐํ•˜๋ฉด์„œ ์ผ์‹œ ์ค‘์ง€๋œ ํ”„๋กœ์„ธ์Šค๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ signal()์—ฐ์‚ฐ์„ ์‹คํ–‰ํ•˜๋ฉด ์žฌ์‹œ์ž‘๋˜์–ด์•ผ ํ•œ๋‹ค. ํ”„๋กœ์„ธ์Šค๋Š” sleep()์— ์˜ํ•ด์„œ ์ผ์‹œ ์ค‘์ง€๋œ๊ณ  wakeup()์— ์˜ํ•ด ์žฌ์‹œ์ž‘๋œ๋‹ค. 

 

์„ธ๋งˆํฌ๋ฅผ ์ด์šฉํ•ด์„œ critical section problem์„ ํ•ด๊ฒฐํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์„ธ๋งˆํฌ์˜ ์ •์˜๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค. 

typedef struct{
int value;
struct process *list; // head of linked list for waiting queue
}semaphore;

๋ณ€๊ฒฝ๋œ wait()์™€ signal()์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค. 

wait(semaphore *S){
S->value--;
if(S->value < 0){
add this process to S->list;
sleep(); //suspend
}
}
signal(semaphore *S){
S->value++;
if(S->value <= 0){
remove a process P from S->list;
wakeup(P); //resume
}
}

wakeup()๊ณผ sleep()๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ์ผ์‹œ ์ค‘์ง€ ๋˜๋Š” ์žฌ์‹คํ–‰์‹œํ‚ค๋Š” ์šด์˜์ฒด์ œ์˜ ๊ธฐ๋ณธ์ ์ธ ์‹œ์Šคํ…œ ์ฝœ์ด๋‹ค. 

์„ธ๋งˆํฌ์˜ ํ”„๋กœ์„ธ์Šค ๋ฆฌ์ŠคํŠธ๋Š” Bounded Waiting์„ ๋ณด์žฅํ•˜๋„๋ก ์ž˜ ๊ตฌํ˜„ํ•ด์•ผ๋งŒ ํ•œ๋‹ค. 

 

๋‹จ์ผ Processor ํ™˜๊ฒฝ์—์„œ๋Š” wait()์™€ signal()์ด atomicํ•˜๊ฒŒ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๊ธˆ์ง€ํ•จ์œผ๋กœ์จ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋‹ค์ค‘ ์ฝ”์–ด ํ™˜๊ฒฝ์—์„œ๋Š” ๋ชจ๋“  ์ฒ˜๋ฆฌ ์ฝ”์–ด์—์„œ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๊ธˆ์ง€ํ•˜์—ฌ์•ผ๋งŒ ํ•œ๋‹ค. ์ด๋Š” ๋งค์šฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์„ฑ๋Šฅ์„ ์‹ฌ๊ฐํ•˜๊ฒŒ ๊ฐ์†Œ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ์œผ๋กœ ๋งŽ์€ ๋ถ€๋ถ„์„ ๊ณ ๋ คํ•ด์•ผ๋งŒ ํ•œ๋‹ค. 


7. Monitors(๋ชจ๋‹ˆํ„ฐ)

mutex lock ๋˜๋Š” Semaphore๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์—๋„ ํƒ€์ด๋ฐ ์˜ค๋ฅ˜๋Š” ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, wait()์™€ signal()์˜ ์ˆœ์„œ๊ฐ€ ๋’ค๋ฐ”๋€Œ๋Š” ๊ฒฝ์šฐ, Critical Section์ด ๋๋‚˜๊ณ  signal()๋Œ€์‹  wait()๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฒฝ์šฐ์— ๊ทธ๋ ‡๋‹ค.

 

Semaphore์˜ ์˜ฌ๋ฐ”๋ฅธ ์‚ฌ์šฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค. 

wait(mutex);
/* critical section */
signal(mutex);

 

์ด๋Ÿฌํ•œ ์˜ค๋ฅ˜๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ํ•œ๊ฐ€์ง€ ์ „๋žต์€ ๋ชจ๋‹ˆํ„ฐ(Monitor)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

1) Monitors๋ž€?

ํŽธ๋ฆฌํ•˜๊ณ  ํšจ๊ณผ์ ์ธ ๋™๊ธฐํ™” ๋„๊ตฌ๋ฅผ ์ง€์ง€ํ•˜๊ธฐ ์œ„ํ•œ high-level language contructs.

  • Monitor type: ๋ชจ๋‹ˆํ„ฐ ๋‚ด๋ถ€์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ •์˜ํ•œ mutual exclusion์ด ๋ณด์žฅ๋˜๋Š” ์ผ๋ จ์˜ ์—ฐ์‚ฐ์ž ์ง‘ํ•ฉ์„ ํฌํ•จํ•˜๋Š” ADT์ด๋‹ค. 
    • ADT(์ถ”์ƒํ™”๋œ ๋ฐ์ดํ„ฐ ํ˜•, abstract data type)์€ ๋ฐ์ดํ„ฐ์™€ ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋“ค์˜ ์ง‘ํ•ฉ์„ ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ๋ฌถ์–ด ๋ณดํ˜ธํ•œ๋‹ค. ์ด๋•Œ ํ•จ์ˆ˜์˜ ๊ตฌํ˜„์€ ADT์˜ ํŠน์ •ํ•œ ๊ตฌํ˜„๊ณผ ๋…๋ฆฝ์ ์ด๋‹ค. 
    • ์˜ค์ง ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค๋งŒ ๋ชจ๋‹ˆํ„ฐ์—์„œ activeํ•˜๋‹ค(mutual exclusion)
  • Pseudocode syntax of monitor
monitor monitor-name
{
//shared variable declarations
function P1 (...) {...}
function P2 (...) {...}
function P3 (...) {...}
initialization code (...) {...}
}

2) Schematic view of a Monitor

monitor์˜ ๊ฐœ๋žต๋„๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

๋ชจ๋‹ˆํ„ฐ ์•ˆ์—๋Š” 3๊ฐ€์ง€์˜ components๋“ค์ด ์ •์˜๊ฐ€ ๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ, shared data, operations, initialization code๊ฐ€ ์ด์— ํ•ด๋‹น๋œ๋‹ค. 
๋˜ํ•œ entry queue๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ, entry queue์•ˆ์—๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ๋‹ค. ์ด ํ”„๋กœ์„ธ์Šค๋“ค์€ ๋ชจ๋‹ˆํ„ฐ์— ๋“ค์–ด๊ฐ€๊ธฐ ์œ„ํ•ด ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋‹ค. 

 

๋ชจ๋‹ˆํ„ฐ ๊ตฌ์กฐ๋ฌผ์€ ๋ชจ๋‹ˆํ„ฐ ์•ˆ์— ํ•ญ์ƒ ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค๋งŒ์ด ํ™œ์„ฑํ™”๋˜๋„๋ก ๋ณด์žฅํ•ด ์ค€๋‹ค(mutual exclusion). ํ•˜์ง€๋งŒ ์ง€๊ธˆ๊นŒ์ง€ ์ •์˜ํ•œ ๋ชจ๋‹ˆํ„ฐ ๊ตฌ์กฐ๋ฌผ์€ ์–ด๋–ค ๋™๊ธฐํ™” ๊ธฐ๋ฒ•์„ ๋ชจ๋ธ๋งํ•˜๋Š” ๋ฐ์—๋Š” ์ถฉ๋ถ„ํ•œ ๋Šฅ๋ ฅ์„ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค. 

 

monitor์˜ ์˜ˆ

- Monitor in Java : Synchronized method

class Producer{
private int product;
...
private synchronized void produce(); //mutually exclusive
}

synchronized method๋ฅผ ์ด์šฉํ•˜์—ฌ mutual exclusion์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

๋งŒ์•ฝ ์œ„ ์ฝ”๋“œ์—์„œ private synchronized void B();๋ผ๋Š” ํ•จ์ˆ˜๊ฐ€ ์ถ”๊ฐ€๊ฐ€ ๋œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. Process A, Process B๊ฐ€ ์žˆ๋Š” ์ƒํ™ฉ์—์„œ PA๊ฐ€ produce()ํ•จ์ˆ˜์— ์ ‘๊ทผํ•˜๊ธธ ์›ํ•˜๊ณ  PB๊ฐ€ B()ํ•จ์ˆ˜์— ์ ‘๊ทผํ•˜๊ธฐ ์›ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด Synchronized method์— ์˜ํ•ด์„œ ์˜ค์ง ํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ•˜๋‚˜์˜ ํ•จ์ˆ˜๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

3) Condition Variables

Condition Variables์€ ์ถ”๊ฐ€์ ์ธ ๋™๊ธฐํ™” ๊ธฐ๋ฒ•(additional synchronization mechanism)์ด๋‹ค. 

  • Condition ํ˜•์˜ ๋ณ€์ˆ˜ ์ •์˜(Variable declaration)
    • condition x, y;
  • conditionํ˜• ๋ณ€์ˆ˜์— ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ๋Š” ์—ฐ์‚ฐ์€ ์˜ค์ง wait()์™€ signal()์ด๋‹ค. 
    • x.wait(); // ์ด ์—ฐ์‚ฐ์„ ํ˜ธ์ถœํ•œ ํ”„๋กœ์„ธ์Šค๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ x.signal()์„ ํ˜ธ์ถœํ•  ๋•Œ๊นŒ์ง€ ์ผ์‹œ ์ค‘์ง€ ๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.
    • x.signal(); // ์ผ์‹œ ์ค‘์ง€๋œ ํ”„๋กœ์„ธ์Šค๋ฅผ ํ’€์–ด์ค€๋‹ค. ๋งŒ์•ฝ waitingํ•˜๊ณ  ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์—†๋‹ค๋ฉด ์•„๋ฌด์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค. 

Monitor with Condition Variables

4) Condition Variables Choices

  • ๋งŒ์•ฝ process P๊ฐ€ x.signal()์„ ํ˜ธ์ถœํ•˜๊ณ , process Q๊ฐ€ x.wait()์—์„œ ์ผ์‹œ ์ค‘๋‹จ ๋๋‹ค๋ฉด, ๋ฌด์—‡์ด ๋‹ค์Œ์— ์ผ์–ด๋‚ ๊นŒ?
    • Q์™€ P ๋ชจ๋‘ ๋™์‹œ์— ์‹คํ–‰๋  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— Q๊ฐ€ ์ง„ํ–‰๋๋‹ค๋ฉด P๋Š” ๋Œ€๊ธฐํ•ด์•ผ ํ•œ๋‹ค. ๋ชจ๋‹ˆํ„ฐ์—์„œ๋Š” ์˜ค์ง ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค๋งŒ ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ž˜์„œ ์—ฌ๊ธฐ์—๋Š” ๋‘๊ฐ€์ง€ ์ƒํ™ฉ์ด ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
  • ๋‘ ๊ฐ€์ง€ ์˜ต์…˜(์ƒํ™ฉ) 
    • Signal and wait: ๋งŒ์•ฝ P๊ฐ€ x.signal()์„ ๋ถˆ๋ €๋‹ค๋ฉด Q๊ฐ€ ์‹คํ–‰๋˜๊ณ  P๋Š” Q๊ฐ€ monitor์„ ๋– ๋‚ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ฑฐ๋‚˜ ๋‹ค๋ฅธ condition์„ ๊ธฐ๋‹ค๋žด์•ผ ํ•œ๋‹ค. (Q๊ฐ€ ๋จผ์ € ์‹œ์ž‘)
    • Signal and continue: P๊ฐ€ x.signal()์„ ๋ถˆ๋ €๋‹ค๋ฉด Q๋Š” P๊ฐ€ monitor์„ ๋– ๋‚ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ฑฐ๋‚˜ ๋‹ค๋ฅธ condition์„ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค. (P๊ฐ€ ๋๋‚ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ธฐ)
    • ์œ„์˜ ๋‘˜์€ ๋ชจ๋‘ ์žฅ๋‹จ์ ์ด ์กด์žฌํ•œ๋‹ค. ํ•˜์ง€๋งŒ signal and continue๊ฐ€ ์กฐ๊ธˆ ๋” reasonableํ•˜๋‹ค.

 

5) Implementing a Monitor Using Semaphores

๊ฐ ๋ชจ๋‹ˆํ„ฐ๋งˆ๋‹ค mutex๋ผ๋Š” binary semaphore๊ฐ€ ์ •์˜๋˜๊ณ  ๊ทธ ์ดˆ๊ธฐ ๊ฐ’์€ 1์ด๋‹ค. ํ”„๋กœ์„ธ์Šค๋Š” ๋ชจ๋‹ˆํ„ฐ๋กœ ๋“ค์–ด๊ฐ€๊ธฐ ์ „์— wait(mutex)๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๋ชจ๋‹ˆํ„ฐ๋ฅผ ๋‚˜์˜จ ํ›„์— signal(mutex)์„ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค. 

  • Funtions to implement(์‹คํ–‰์‹œํ‚ฌ ํ•จ์ˆ˜๋“ค)
    • External procedures
    • wait() of condition variable
    • signal() of condition variable

 

๋ชจ๋‹ˆํ„ฐ ๊ตฌํ˜„ ์‹œ signal-and-wait๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค. signaling ํ”„๋กœ์„ธ์Šค๋Š” ์‹คํ–‰ ์žฌ๊ฐœ๋˜๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ชจ๋‹ˆํ„ฐ๋ฅผ ๋– ๋‚˜๋Š”์ง€ ์•„๋‹ˆ๋ฉด wait()ํ•  ๋•Œ๊นŒ์ง€ ๊ทธ ์ž์‹ ์ด ๋‹ค์‹œ ๊ธฐ๋‹ค๋ ค์•ผ ํ•˜๋ฏ€๋กœ next๋ผ๋Š” binary semaphore ๊ฐ€ ์ถ”๊ฐ€๋กœ ํ•„์š”ํ•˜๊ฒŒ ๋˜๊ณ  0์œผ๋กœ ์ดˆ๊ธฐํ™” ๋œ๋‹ค. 

  • ๋‘๊ฐœ์˜ semaphores๊ฐ€ ํ•„์š”ํ•˜๋‹ค. 
    • semaphore mutex = 1; // mutual exclusion
    • semaphore next = 0; // signaling process should wait until the resumed process leaves monitor
    • int next_count = 0; // the number of precesses suspended on next(semaphore)
  • External procedure F
wait(mutex);
...
body of F;
...
if(next_count > 0)
signal(next)
else
signal(mutex);
  • Conditional variables
    • Required data
      • semaphore x_sem; // (initially, 0)
      • int x_count = 0; // wait ํ•˜๊ณ  ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค์˜ ์ˆ˜
x.wait(){
x_count++;
if(next_count > 0)
signal(next);
else
signal(mutex);
wait(x_sem);
x_count--;
}
x.signal(){
if(x_count > 0){
next_count++;
signal(x_sem);
wait(next);
next_count--;
}
}

6) Resuming Precesses within a Monitor

  • If several processes queued on conditio variable x, and x.signal() is executed, which process should be resumed?(์กฐ๊ฑด ๋ณ€์ˆ˜ x์— ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ผ์‹œ ์ค‘์ง€ ๋˜์–ด ์žˆ์„ ๋•Œ, ์–ด๋– ํ•œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ˆ˜ํ–‰ ์žฌ๊ฐœ์‹œํ‚ฌ ๊ฒƒ์ธ๊ฐ€?)
  • FCFS(First Come First Served)์ˆœ์ด ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐ์ด ๋“ค์ง€๋งŒ ๋งŽ์€ ๊ฒฝ์šฐ ์ด๋Ÿฌํ•œ ๊ฐ„๋‹จํ•œ ์Šค์ผ€์ค„๋ง ๊ธฐ๋ฒ•์€ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๋‹ค. 
  • ์ด๋ฅผ ์œ„ํ•ด conditional-wait ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 
    • ์ด ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง„๋‹ค.
    • x.wait(c); 
    • ์—ฌ๊ธฐ์„œ c๋Š” ์ •์ˆ˜์ด๋ฉฐ, ์šฐ์„ ์ˆœ์œ„ ๋ฒˆํ˜ธ(priority number)๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค. ์ผ์‹œ ์ค‘์ง€ ๋˜๋Š” ํ”„๋กœ์„ธ์Šค์˜ ์ด๋ฆ„๊ณผ ํ•จ๊ป˜ ์ €์žฅ๋œ๋‹ค. 
    • x.signal()์ด ์ˆ˜ํ–‰๋˜๋ฉด ๊ฐ€์žฅ ์ž‘์€ ์šฐ์„ ์ˆœ์œ„ ๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์ง„ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋‹ค์Œ๋ฒˆ์— ์ˆ˜ํ–‰ ์žฌ๊ฐœ ๋œ๋‹ค. 

7) Single Resource Allocation

๋ชจ๋‹ˆํ„ฐ๋Š” Resource๋ฅผ ์‚ฌ์šฉํ•  ์ตœ๋Œ€ ์‹œ๊ฐ„์„ ์ง€์ •ํ•˜๋Š” ์šฐ์„  ์ˆœ์œ„ ๋ฒˆํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ๊ฒฝ์Ÿ ํ”„๋กœ์„ธ์Šค ์ค‘์—์„œ ํ•œ ๊ฐœ์˜ Resource์„ ํ• ๋‹นํ•ด ์ค€๋‹ค. ์ด Resource๋ฅผ ์•ก์„ธ์Šค ํ•˜๋ ค๋Š” ํ”„๋กœ์„ธ์Šค๋Š” ์•„๋ž˜์˜ ์ˆœ์„œ๋ฅผ ๋”ฐ๋ผ์•ผ ํ•œ๋‹ค. 

R.acquire(t);
...
access the resource;
...
R.release;

์—ฌ๊ธฐ์„œ R์€ ResourceAllocator type์˜ ํ•œ instance์ด๋‹ค. 

 

8) A Monitor to Allocate Single Resource

์•„๋ž˜๋Š” ADT์ธ ResourceAllocator ๋ชจ๋‹ˆํ„ฐ๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ด๋‹ค. 

monitor ResourceAllocator{
boolean busy;
condition x;
void acquire(int time){
if(busy)
x.wait(time);
busy = true;
}
void release(){
busy = FALSE;
x.signal();
}
initialization code(){
busy = false;
}
}

8. Liveness(๋ผ์ด๋ธŒ๋‹ˆ์Šค)

๋ผ์ด๋ธŒ๋‹ˆ์Šค๋ž€ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹คํ–‰ life cycle ๋™์•ˆ ์ง„ํ–‰(progress)๋˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์‹œ์Šคํ…œ์ด ์ถฉ์กฑํ•ด์•ผ ํ•˜๋Š” ์ผ๋ จ์˜ ์†์„ฑ์„ ๋งํ•œ๋‹ค. 

๋ผ์ด๋ธŒ๋‹ˆ์Šค ์‹คํŒจ์˜ ์˜ˆ: ํ”„๋กœ์„ธ์Šค๊ฐ€ lock์„ ์–ป๊ธฐ ์œ„ํ•ด ๋ฌด๊ธฐํ•œ ๋Œ€๊ธฐํ•˜๋Š” ๊ฒƒ

 

liveness ์‹คํŒจ์˜ ์ด์œ 

  • Deadlock
  • Priority inversion
  • Many other reasons
  1. Deadlock(๊ต์ฐฉ์ƒํƒœ)
    • ๋Œ€๊ธฐ ํ๋ฅผ ๊ฐ€์ง„ Semaphore ๊ตฌํ˜„์—์„œ ๋‘ ๊ฐœ ์ด์ƒ์˜ ํ”„๋กœ์„ธ์Šค๋“ค์ด, ์˜ค๋กœ์ง€ ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋“ค ์ค‘ ํ•˜๋‚˜์— ์˜ํ•ด์„œ๋งŒ ์•ผ๊ธฐ๋  ์ˆ˜ ์žˆ๋Š” signal()์„ ๋ฌดํ•œ์ • ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฐ ์ƒํƒœ์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ, ์ด๋“ค ํ”„๋กœ์„ธ์Šค๋“ค์„ deadlock์ด๋ผ๊ณ  ํ•œ๋‹ค. 
    • ์ฆ‰, ๋‘ ๊ฐœ ์ด์ƒ์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค ์ค‘ ํ•˜๋‚˜๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ด๋ฒคํŠธ๋ฅผ ๋ฌดํ•œ์ • ๋Œ€๊ธฐํ•˜๊ณ  ์žˆ๋Š” ์ƒํ™ฉ์ด๋‹ค. 
    • ์ด๋•Œ "์ด๋ฒคํŠธ"๋ž€, mutex lock๊ณผ Semaphore๊ฐ™์€ Resource์˜ ํš๋“๊ณผ ๋ฐฉ์ถœ์ด๋‹ค. 
  2. Starvation (infinite blocking) 
    • Semaphore์—์„œ ํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฌดํ•œ์ •ํ•˜๊ฒŒ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋Š” ์ƒํ™ฉ
    • ex) waiting list is implemented by LIFO order
  3. Priority inversion(์šฐ์„ ์ˆœ์œ„ ์—ญ์ „)
    • ๋†’์€ ์šฐ์„ ์ˆœ์œ„ ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ˜„์žฌ ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„ ํ”„๋กœ์„ธ์Šค ๋˜๋Š” ์—ฐ์†๋œ ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„ ํ”„๋กœ์„ธ์Šค๋“ค์— ์˜ํ•ด ์ ‘๊ทผ๋˜๊ณ  ์žˆ๋Š” ์ปค๋„ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์žˆ์„ ๋•Œ ์Šค์ผ€์ค„๋ง์˜ ์–ด๋ ค์›€์ด ์ƒ๊ธฐ๊ฒŒ ๋œ๋‹ค. 
    • ์ปค๋„๋ฐ์ดํ„ฐ๋Š” ๋ฝ์— ์˜ํ•ด ๋ณดํ˜ธ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž์›์˜ ์‚ฌ์šฉ์„ ๋งˆ์น  ๋•Œ๊นŒ์ง€ ๋†’์€ ์šฐ์„ ์ˆœ์œ„ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค. ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋˜ ๋‹ค๋ฅธ ๋†’์€ ์šฐ์„ ์ˆœ์œ„ ํ”„๋กœ์„ธ์Šค์— ์˜ํ•ด ์„ ์ ๋˜๋Š” ๊ฒฝ์šฐ์— ์ƒํ™ฉ์€ ๋”์šฑ ๋ณต์žกํ•ด์ง„๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„ ํ”„๋กœ์„ธ์Šค๋Š” ๊ณ„์† ๊ธฐ๋‹ค๋ ค์•ผ๋งŒ ํ•œ๋‹ค. 
      • ์˜ˆ์‹œ**
      • L, M, H ์„ธ ๊ฐœ์˜ process๊ฐ€ ์กด์žฌ
      • ์šฐ์„ ์ˆœ์œ„๋Š” L < M < H
      • H๋Š” L์— ์˜ํ•ด Semaphore S๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.
      • L์€ M์„ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค. ๊ทธ๊ฒƒ์˜ ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„ ๋•Œ๋ฌธ์—
      • ๋”ฐ๋ผ์„œ H๋„ M์„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

 

'CS > Operating System' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Operating System] ์šด์˜์ฒด์ œ Caching [2]  (0) 2024.03.09
[Operating System] ์šด์˜์ฒด์ œ Caching [1]  (0) 2024.03.07
[์šด์˜์ฒด์ œ] Chapter7. Synchronization Examples  (0) 2022.06.01
  • 1.  Background
  • 2. The Critical-Section Problem
  • 3. Peterson's Solution
  • 4. Hardware Support for Synchronization
  • 5. Mutex Locks
  • 6. Semaphores
  • 7. Monitors(๋ชจ๋‹ˆํ„ฐ)
  • 8. Liveness(๋ผ์ด๋ธŒ๋‹ˆ์Šค)
'CS/Operating System' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [Operating System] ์šด์˜์ฒด์ œ Caching [2]
  • [Operating System] ์šด์˜์ฒด์ œ Caching [1]
  • [์šด์˜์ฒด์ œ] Chapter7. Synchronization Examples
๐Ÿธminzzi
๐Ÿธminzzi

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”

๊ฐœ์ธ์ •๋ณด

  • ํ‹ฐ์Šคํ† ๋ฆฌ ํ™ˆ
  • ํฌ๋Ÿผ
  • ๋กœ๊ทธ์ธ

๋‹จ์ถ•ํ‚ค

๋‚ด ๋ธ”๋กœ๊ทธ

๋‚ด ๋ธ”๋กœ๊ทธ - ๊ด€๋ฆฌ์ž ํ™ˆ ์ „ํ™˜
Q
Q
์ƒˆ ๊ธ€ ์“ฐ๊ธฐ
W
W

๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๊ธ€

๊ธ€ ์ˆ˜์ • (๊ถŒํ•œ ์žˆ๋Š” ๊ฒฝ์šฐ)
E
E
๋Œ“๊ธ€ ์˜์—ญ์œผ๋กœ ์ด๋™
C
C

๋ชจ๋“  ์˜์—ญ

์ด ํŽ˜์ด์ง€์˜ URL ๋ณต์‚ฌ
S
S
๋งจ ์œ„๋กœ ์ด๋™
T
T
ํ‹ฐ์Šคํ† ๋ฆฌ ํ™ˆ ์ด๋™
H
H
๋‹จ์ถ•ํ‚ค ์•ˆ๋‚ด
Shift + /
โ‡ง + /

* ๋‹จ์ถ•ํ‚ค๋Š” ํ•œ๊ธ€/์˜๋ฌธ ๋Œ€์†Œ๋ฌธ์ž๋กœ ์ด์šฉ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ํ‹ฐ์Šคํ† ๋ฆฌ ๊ธฐ๋ณธ ๋„๋ฉ”์ธ์—์„œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.