br0nzu

[OS-๋ฐ˜ํšจ๊ฒฝ] Process Synchronization(Concurrency control)

br0nzu br0nzu Computer Science #OS

Race Condition, Critical Section, Atomic Instruction, Semaphore, Monitor..๐Ÿค

E-Box,S-Box

์ปดํ“จํ„ฐ์—์„œ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผ(์—ฐ์‚ฐ)์€ ์‹คํ–‰ ์ฃผ์ฒด(E-box)์™€ ๋ฐ์ดํ„ฐ ์ €์žฅ ๊ณต๊ฐ„(S-box)์˜ ์ƒํ˜ธ์ž‘์šฉ์œผ๋กœ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ๋•Œ๋Š” ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์—†์ง€๋งŒ, ์—ฌ๋Ÿฌ ์‹คํ–‰ ์ฃผ์ฒด๊ฐ€ ํ•˜๋‚˜์˜ ๊ณต์œ  ์ž์›(S-box)์— ๋™์‹œ์— ์ ‘๊ทผํ•  ๋•Œ Race Condition์ด๋‚˜ ๋ฐ์ดํ„ฐ ๋ถˆ์ผ์น˜๊ฐ€ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์šด์˜์ฒด์ œ๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ๋ง‰๊ณ  ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœ์„ธ์Šค ๊ฐ„์˜ ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ์กฐ์œจํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ์ด์™€ ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค ๋™๊ธฐํ™” ๋ฌธ์ œ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Race Condition

Race Condition์€ ์—ฌ๋Ÿฌ ์‹คํ–‰ ์ฃผ์ฒด๊ฐ€ ๊ฐ™์€ ๊ณต์œ  ์ž์›์„ ๋™์‹œ์— ๋‹ค๋ฃฐ ๋•Œ, ์ˆœ์„œ ๋ฐ ํƒ€์ด๋ฐ์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์ง€๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์šด์˜์ฒด์ œ์—์„œ Race Condition์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Kerenl ์ˆ˜ํ–‰ ์ค‘ ์ธํ„ฐ๋ŸฝํŠธ ๋ฐœ์ƒ ์‹œ
  • Process๊ฐ€ System Call์„ ํ•˜์—ฌ Kernel mode๋กœ ์ˆ˜ํ–‰ ์ค‘์ธ๋ฐ Context Switch๊ฐ€ ์ผ์–ด๋‚œ ๊ฒฝ์šฐ
  • Multiprocessor์—์„œ Shared Memory ๋‚ด์˜ Kernel Data์— ์ ‘๊ทผํ•  ๋•Œ

๋จผ์ € ์ปค๋„ ์ˆ˜ํ–‰ ์ค‘ ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด Race Condition์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Kerenl Interrupt

๊ณ ๊ธ‰ ์–ธ์–ด์—์„œ count++์™€ ๊ฐ™์€ ์ฆ๊ฐ€ ์—ฐ์‚ฐ์€ ํ•œ ์ค„์˜ ์ฝ”๋“œ์ง€๋งŒ, ์‹ค์ œ ๊ธฐ๊ณ„์–ด์—์„œ๋Š” load, inc, store ๋ช…๋ น์–ด๋กœ ๋‚˜๋‰˜์–ด ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ์ด 3๋‹จ๊ณ„ ๊ณผ์ •์ด atomic1ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ๋ช…๋ น์–ด๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋„์ค‘ ๋‹ค๋ฅธ ๋ช…๋ น์–ด๋กœ ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๊ฒฐ๊ณผ๊ฐ€ ์ ์šฉ์ด ์•ˆ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์ปค๋„์ด count++๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด load โ†’ inc โ†’ store ์ˆœ์„œ๋กœ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•œ๋‹ค๊ณ  ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ load๋กœ count ๊ฐ’์„ ๋ ˆ์ง€์Šคํ„ฐ์— ์˜ฌ๋ฆฐ ์งํ›„ ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ , ์ธํ„ฐ๋ŸฝํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ count--๋ฅผ ์ˆ˜ํ–‰ํ•œ ๋’ค ๋ณต๊ท€ํ•˜๋ฉด, ํ•ด๋‹น ๊ฐ์†Œ ์—ฐ์‚ฐ์ด count ๋ณ€์ˆ˜์— ๋ฐ˜์˜์ด ์•ˆ๋ฉ๋‹ˆ๋‹ค. ์ปค๋„์€ ์ธํ„ฐ๋ŸฝํŠธ ๋™์•ˆ count ๊ฐ’์ด ๋ณ€๊ฒฝ๋๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ ์ˆ˜ ์—†์–ด์„œ, ๋ ˆ์ง€์Šคํ„ฐ์— ๋‚จ์•„ ์žˆ๋˜ ๊ฐ’์— inc๋ฅผ ์ ์šฉํ•œ ๋’ค ๊ทธ๋Œ€๋กœ storeํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด์ฒ˜๋Ÿผ ์ปค๋„ ์ˆ˜ํ–‰ ์ค‘ ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด Race Condition์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ณต์œ  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐฑ์‹ ํ•˜๋Š” ๊ตฌ๊ฐ„์—์„œ๋Š” ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์ž ์‹œ disableํ•˜์—ฌ ํ•ด๋‹น ์ฝ”๋“œ๊ฐ€ ๋Š๊ธฐ์ง€ ์•Š๋„๋ก ๋ณด์žฅํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹œ์Šคํ…œ ์ฝœ์„ ํ•˜์—ฌ ์ปค๋„ ๋ชจ๋“œ๋กœ ์ˆ˜ํ–‰ ์ค‘์ธ๋ฐ ๋ฌธ๋งฅ ๊ตํ™˜์ด ์ผ์–ด๋‚œ ๊ฒฝ์šฐ์—๋„ Race Condition์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Process_Kernel

์œ„ ์‚ฌ์ง„์ด ์ง๊ด€์ ์ด๊ณ  ์ด์ „ Race Condition์ด ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒฝ์šฐ์™€ ๊ฑฐ์˜ ๋น„์Šทํ•œ ๋‚ด์šฉ์ด๋ผ์„œ ์ถ”๊ฐ€์ ์ธ ์„ค๋ช…์€ ์ƒ๋žตํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ปค๋„ ๋ชจ๋“œ์—์„œ CPU๋ฅผ preemptํ•˜์ง€ ์•Š๊ณ , ์œ ์ € ๋ชจ๋“œ๋กœ ๋Œ์•„ ์™”์„ ๋•Œ preemptํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฉ€ํ‹ฐ ํ”„๋กœ์„ธ์„œ์—์„œ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ๋‚ด ์ปค๋„ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•œ๋‹ค๋ฉด Race Condition์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Multiprocessor_memory

๋‹จ์ผ CPU์—์„œ๋Š” ์ปค๋„์ด ๊ณต์œ  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐฑ์‹ ํ•˜๋Š” ๋™์•ˆ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์ž ์‹œ disableํ•˜๋ฉด Race Condition์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์„œ๋Š” ํ•œ CPU์—์„œ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ disableํ•ด๋„ ๋‹ค๋ฅธ CPU๋Š” ๊ณ„์† ์ปค๋„ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Race Condition์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ปค๋„ ๋ฐ์ดํ„ฐ์— ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ CPU๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œํ•œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ๊ณต์œ  ์ปค๋„ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ๋•Œ๋งˆ๋‹ค lock์„ ๊ฑธ๊ณ  ์ž‘์—…์ด ๋๋‚˜๋ฉด unlock์„ ํ•ด, ๋™์‹œ์— ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ง‰๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฒฐ๊ตญ Race Condition์„ ๋ง‰์œผ๋ ค๋ฉด, ๊ณต์œ  ์ž์›์„ ์ ‘๊ทผ/๊ฐฑ์‹ ํ•˜๋Š” ์ฝ”๋“œ ๊ตฌ๊ฐ„์„ โ€˜๋™์‹œ์— ์‹คํ–‰๋˜์ง€ ์•Š๊ฒŒโ€™ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์šด์˜์ฒด์ œ์—์„œ๋Š” ์ด ๊ตฌ๊ฐ„์„ Critical Section2์ด๋ผ๊ณ ํ•ฉ๋‹ˆ๋‹ค.

The Critical Section Problem

Critical Section ๋ฌธ์ œ๋Š” ์—ฌ๋Ÿฌ ์‹คํ–‰ ์ฃผ์ฒด๊ฐ€ ๊ณต์œ  ์ž์›์— ๋™์‹œ์— ์ ‘๊ทผํ•˜์ง€ ์•Š๋„๋ก, ํ•œ ๋ฒˆ์— ํ•˜๋‚˜๋งŒ ์ง„์ž…ํ•˜๊ฒŒ ๋ณด์žฅํ•˜๋Š” ๋™๊ธฐํ™” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. Critical Section ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Mutual Exclusion, Progress, Bounded Waiting์„ ๋ชจ๋‘ ๋งŒ์กฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • Mutual Exclusion: ํ•œ ์‹œ์ ์— Critical Section์—๋Š” ํ•˜๋‚˜์˜ ์‹คํ–‰ ์ฃผ์ฒด๋งŒ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ
  • Progress: Critical Section์— ๋“ค์–ด๊ฐˆ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ณ ๋ฅด๋Š” ๊ฒฐ์ •์ด ๋ฌดํ•œํžˆ ๋ฏธ๋ค„์ง€๋ฉด ์•ˆ๋จ
  • Bounded Waiting: ์–ด๋–ค ํ”„๋กœ์„ธ์Šค๊ฐ€ Critical Section์— ๋“ค์–ด๊ฐ€๊ณ  ์‹ถ์–ด์„œ ์š”์ฒญ์„ ํ–ˆ์œผ๋ฉด, ๊ทธ ์ดํ›„๋กœ๋Š” ์–ธ์  ๊ฐ€ ๋ฐ˜๋“œ์‹œ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ

Initial Attempts to Solve Problem

Critical Section ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ์‹œ๋„ํ•œ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

critical section๊ณผ ์•„๋‹Œ ์˜์—ญ์œผ๋กœ ๊ตฌ๋ถ„ํ•˜๊ณ , ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•ด ๋™๊ธฐํ™” ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. Critical Section์— ์ ‘๊ทผํ•˜๊ธฐ ์ „ ๋™๊ธฐํ™” ๋ณ€์ˆ˜๋ฅผ ํ™•์ธํ•˜์—ฌ Critical Section์— ์ง„์ž… ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๊ณ , Critical Section์— ์ง„์ž…ํ•œ ์ดํ›„์— ๋™๊ธฐํ™” ๋ณ€์ˆ˜๋ฅผ ํ•ด์ œํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™๊ธฐํ™” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ข€ ๋” ๊ตฌ์ฒด์ ์ธ ์„ค๋ช…์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Algorithm 1

int turn;
initially turn = 0;

๋™๊ธฐํ™” ๋ณ€์ˆ˜(turn)๋Š” ์ž์‹ ์˜ ์ฐจ๋ก€๋ผ๋Š” ๊ฒƒ์„ ์•Œ๋ ค์ฃผ๋Š” ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค.

do {
while (turn != 0); /* My turn? */
critical section
turn = 1; /* Now it's your turn */
remainder section
} while (1);

์ด์ฒ˜๋Ÿผ ์ž์‹ ์˜ ์ฐจ๋ก€๊ฐ€ ๋˜๋ฉด critical section์— ์ ‘๊ทผํ•˜๊ณ , ์ ‘๊ทผ ์ดํ›„์—๋Š” ๋™๊ธฐํ™” ๋ณ€์ˆ˜๋ฅผ ํ•ด์ œํ•˜์—ฌ ๋™๊ธฐํ™”๋ฅผ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ์‹์€ ์„œ๋กœ ๋ฐ˜๋“œ์‹œ ๊ต๋Œ€๋กœ ๋“ค์–ด๊ฐ€์•ผ๋งŒ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— Critical Section์— ์ž์ฃผ ์ ‘๊ทผํ•ด์•ผํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ๋‹ค๋ฉด ๋น„ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.

Algorithm 2

boolean flag[2];
initially flag[๋ชจ๋‘] = false; /* no one is in CS */

ํ”„๋กœ์„ธ์Šค๋งˆ๋‹ค ๋™๊ธฐํ™” ๋ณ€์ˆ˜(flag)๋ฅผ ์„ค์ •ํ•˜์—ฌ critical section์— ๋“ค์–ด๊ฐ€๊ณ  ์‹ถ๋‹ค๋ฉด true๋กœ ๊ฐ’์„ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

do {
flag[i] = true; /* Pretend I am in */
while (flag[j]); /* Is he also in? then wait */
critical section
flag[i] = false; /* I am out now */
remainder section
} while (1);

์ด ๋ฐฉ๋ฒ•์€ Mutual Exclusion์„ ๋งŒ์กฑํ•˜์ง€๋งŒ, ํ”„๋กœ์„ธ์Šค๋“ค์ด ๋ชจ๋‘ flag๋ฅผ ์„ค์ •ํ•œ๋‹ค๋ฉด Progress์™€ Bounded Waiting์„ ๋งŒ์กฑํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ํ”„๋กœ์„ธ์Šค๋“ค์ด while (flag[j]);์—์„œ ๋Š์ž„์—†์ด ์–‘๋ณดํ•˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Algorithm 3(Petersonโ€™s Algorithm)

do {
flag[i] = true;
turn = j; /* Set to his turn */
while (flag[j] && turn == j); /* wait only if.. */
critical section
flag[i] = false;
remainder section
} while (1);

์ด๋Š” Algorithm 1๊ณผ Algorithm 2๋ฅผ ๊ฒฐํ•ฉํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์„œ๋กœ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋“ค์ด critical section์— ์ ‘๊ทผํ•˜๊ณ  ์‹ถ์„ ๋•Œ, ์šฐ์„ ๊ถŒ(turn = j)์ด ์žˆ๋‹ค๋ฉด ์šฐ์„ ๊ถŒ์ด ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋จผ์ € ์ง„์ž…ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์ดํ›„, ์šฐ์„ ๊ถŒ์ด ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ critical section์—์„œ ๋‚˜์™”๋‹ค๋ฉด critical section์— ์ ‘๊ทผํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ž…๋‹ˆ๋‹ค.

Mutual Exclusion, Progress, Bounded Waiting์„ ๋ชจ๋‘ ๋งŒ์กฑํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด์ง€๋งŒ, while (flag[j] && turn == j);์กฐ๊ฑด์ด ํ’€๋ฆด ๋•Œ๊นŒ์ง€ while์—์„œ ๊ณ„์† ์กฐ๊ฑด์„ ํ™•์ธํ•˜๋ฏ€๋กœ CPU๋ฅผ ๊ณ„์† ์†Œ๋ชจํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ Busy Waiting์ด๋ผ ํ•˜๋ฉฐ Spin lock์ด๋ผ๊ณ ๋„ ํ•ฉ๋‹ˆ๋‹ค.

Synchronization Hardware

์ง€๊ธˆ๊นŒ์ง€๋Š” ์†Œํ”„ํŠธ์›จ์–ด์ ์œผ๋กœ Critical Section ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. ํ•˜๋“œ์›จ์–ด์ ์œผ๋กœ Critical Section ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์•„ํ‚คํ…์ฒ˜์—์„œ atomic ๋ช…๋ น์–ด๋ฅผ ์ œ๊ณตํ•˜๋ฉด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Semaphore

์„ธ๋งˆํฌ์–ด๋Š” ์œ„์— ๋‚˜์˜จ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ atomic ๋ช…๋ น์–ด๋ฅผ ์ถ”์ƒํ™” ํ•œ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. ์ฆ‰, ์„ธ๋งˆํฌ์–ด๋Š” ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ณต์œ  ์ž์›์— ๋™์‹œ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ํ”„๋กœ์„ธ์Šค ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ P์™€ V์—ฐ์‚ฐ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

while (S โ‰ค 0) do no-op;
S--;

P์—ฐ์‚ฐ์€ ์ž์›์„ ํš๋“ํ•˜๋Š” ์—ฐ์‚ฐ์œผ๋กœ lock์„ ์ƒ๊ฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

S++;

V์—ฐ์‚ฐ์€ ์ž์›์„ ๋ฐ˜๋‚ฉํ•˜๋Š” ์—ฐ์‚ฐ์œผ๋กœ unlock์„ ์ƒ๊ฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

do {
P(mutex);
critical section
V(mutex);
remainder section
} while (1);

์ด๋Š” ๊ธฐ๋ณธ์ ์ธ ์„ธ๋งˆํฌ์–ด๋ฅผ ํ™œ์šฉํ•œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ํ”ผํ„ฐ์Šจ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ while (...)๋กœ ์กฐ๊ฑด์„ ๊ณ„์† ํ™•์ธํ•ด์•ผ ํ•˜๋ฏ€๋กœ Critical Section์— ๋“ค์–ด๊ฐ€์ง€ ๋ชปํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ CPU๋ฅผ ์ ์œ ํ•œ ์ฑ„๋กœ ๋Œ€๊ธฐํ•˜๋Š” Busy Waiting์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์„ธ๋งˆํฌ์–ด๋Š” ์ž์›์ด ์—†์„ ๋•Œ ํ”„๋กœ์„ธ์Šค๋ฅผ Blockํ•˜๊ณ , ์ž์›์ด ๋ฐ˜ํ™˜๋˜๋ฉด ํ”„๋กœ์„ธ์Šค๋ฅผ Wakeupํ•˜๋Š” Block/Wakeup ๋ฐฉ์‹์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Block/Wakeup Implementation

typedef {
int value; /* semaphore */
struct process *L; /* process wait queue */
} semaphore
  • ์„ธ๋งˆํฌ์–ด ์ •์˜
S.value--; /* prepare to enter */
if (S.value < 0) /* Oops, negative, I cannot enter */
{
add this process to S.L;
block();
}
  • P์—ฐ์‚ฐ ์ •์˜
S.value++;
if (S.value <= 0) {
remove a process P from S.L;
wakeup(P);
}
  • V์—ฐ์‚ฐ ์ •์˜

์ด๋ ‡๊ฒŒ ์„ธ๋งˆํฌ์–ด๋ฅผ Block/Wakeup ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Block/Wakeup ๋ฐฉ์‹์€ CPU ๋‚ญ๋น„๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋Œ€์‹  Block/Wakeup ๊ณผ์ •์—์„œ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ Busy Waiting ๋ฐฉ์‹๊ณผ Block/Wakeup ๋ฐฉ์‹์€ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ์„ ํƒ์ด ๋‹ฌ๋ผ์ง€๋ฉฐ, ์–ด๋–ค ๊ฒฝ์šฐ์— ์–ด๋–ค ๋ฐฉ์‹์ด ๋” ์œ ๋ฆฌํ•œ์ง€ ๋น„๊ตํ•ด๋ณผ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Critical Section์˜ ๊ธธ์ด๊ฐ€ ๊ธด ๊ฒฝ์šฐ Block/Wakeup ๋ฐฉ์‹์ด ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Critical Section์˜ ๊ธธ์ด๊ฐ€ ์งง์œผ๋ฉด Block/Wakeup ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ Busy waiting ์˜ค๋ฒ„ํ—ค๋“œ ๋ณด๋‹ค ๋ณดํ†ต ๋” ํฌ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

Deadlock, Starvation

์„ธ๋งˆํฌ์–ด๋Š” Critical Section ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€๋งŒ, Deadlock๊ณผ Starvation ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Deadlock์€ ๋‘˜ ์ด์ƒ์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์„œ๋กœ๊ฐ€ ๊ฐ€์ง„ ์ž์›์„ ๊ธฐ๋‹ค๋ฆฌ๋ฉฐ, ๋ชจ๋‘๊ฐ€ ์˜์›ํžˆ ์ง„ํ–‰ํ•˜์ง€ ๋ชปํ•˜๋Š” ์ƒํƒœ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ”„๋กœ์„ธ์Šค A๊ฐ€ S1์„ ํš๋“ํ•œ ๋’ค S2๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ณ , ๋™์‹œ์— ํ”„๋กœ์„ธ์Šค B๊ฐ€ S2๋ฅผ ํš๋“ํ•œ ๋’ค S1์„ ๊ธฐ๋‹ค๋ฆฌ๋ฉด ๋‘ ํ”„๋กœ์„ธ์Šค ๋ชจ๋‘ block๋œ ์ฑ„๋กœ ๋ฉˆ์ถ”๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Starvation์€ ํŠน์ • ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ณ„์† ์šฐ์„ ์ˆœ์œ„์—์„œ ๋ฐ€๋ฆฌ๊ฑฐ๋‚˜ ์ž์›์„ ์–ป์ง€ ๋ชปํ•ด, ๋ฌดํ•œํžˆ ๋Œ€๊ธฐํ•˜๋Š” ์ƒํƒœ์ž…๋‹ˆ๋‹ค. Race Condition์—์„œ ๋งค๋ฒˆ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋จผ์ € P(mutex)์— ์„ฑ๊ณตํ•ด ์ž„๊ณ„ ๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ€๋ฉด, ์–ด๋–ค ํ”„๋กœ์„ธ์Šค๋Š” ๊ณ„์† ๊ธฐ๋‹ค๋ฆฌ๊ธฐ๋งŒ ํ•˜๊ณ  ์‹คํ–‰ ๊ธฐํšŒ๋ฅผ ์–ป์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ ๋‹ค๋ฃจ๊ธฐ ๋•Œ๋ฌธ์— ์งง๊ฒŒ ์„ค๋ช…ํ•˜๊ณ  ๋„˜์–ด๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค.

๋™๊ธฐํ™”์™€ ๊ด€๋ จ๋œ ์ „ํ†ต์ ์ธ ๋ฌธ์ œ 3๊ฐ€์ง€

๋™๊ธฐํ™”์™€ ๊ด€๋ จ๋œ ์ „ํ†ต์ ์ธ ๋ฌธ์ œ๊ฐ€ 3๊ฐœ ์žˆ์Šต๋‹ˆ๋‹ค.

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

Monitor

์„ธ๋งˆํฌ์–ด๋Š” ๊ฐ•๋ ฅํ•œ ๋™๊ธฐํ™” ๋„๊ตฌ์ด์ง€๋งŒ, P์™€ V๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ˆœ์„œ๊ฐ€ ์กฐ๊ธˆ๋งŒ ๊ผฌ์—ฌ๋„ Deadlock์ด๋‚˜ Starvation ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์‰ฝ๊ฒŒ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ณต์œ  ์ž์›์„ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•œ ์ฝ”๋“œ๊ฐ€ ์—ฌ๊ธฐ์ €๊ธฐ ํฉ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์—, ํ”„๋กœ๊ทธ๋žจ์ด ์ปค์งˆ์ˆ˜๋ก ๋™๊ธฐํ™” ๋กœ์ง์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์œ ์ง€ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ•œ ๊ฐœ๋…์ด Monitor์ž…๋‹ˆ๋‹ค. Monitor๋Š” ๊ณต์œ  ์ž์›๊ณผ ๊ทธ ์ž์›์„ ์ ‘๊ทผํ•˜๋Š” ์—ฐ์‚ฐ๋“ค์„ ํ•˜๋‚˜์˜ ๋ชจ๋“ˆ๋กœ ๋ฌถ๊ณ , Critical Section ์ง„์ž…์„ ์–ธ์–ด/๋Ÿฐํƒ€์ž„ ์ˆ˜์ค€์—์„œ ๊ด€๋ฆฌํ•ด ๋™๊ธฐํ™”๋ฅผ ๋” ์•ˆ์ „ํ•˜๊ฒŒ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ lock/unlock์„ ์ง์ ‘ ๋งž์ถฐ์ฃผ๊ธฐ๋ณด๋‹ค, Monitor ๋‚ด๋ถ€์—์„œ ์ž๋™์œผ๋กœ Mutual Exclusion์„ ๋ณด์žฅํ•˜๊ณ  ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์กฐ๊ฑด์— ๋”ฐ๋ผ Block/Wakeup์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

Conclusion

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ํ”„๋กœ์„ธ์Šค ๋™๊ธฐํ™” ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋‹ค๋ค„ ๋ดค์Šต๋‹ˆ๋‹ค. Race Condition, Critical Section, Atomic Instruction, Semaphore, Monitor ๋“ฑ ๋งŽ์ด ๋‚ฏ์„ค๊ณ  ์–ด๋ ค์šด ๊ฐœ๋…๋“ค์ด ๋‚˜์™”์ง€๋งŒ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ๋Š” Deadlock์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

References

[1] KCOW ์šด์˜์ฒด์ œ ๋ฐ˜ํšจ๊ฒฝ ๊ฐ•์˜

[2] Operating System Concepts(Silberschatz, Galvin and Gagne)

[3] Classical Problems of Synchronization with Semaphore Solution

Footnotes

  1. atomic: ๋” ์ด์ƒ ์ชผ๊ฐค ์ˆ˜ ์—†๋Š” ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ์ˆ˜ํ–‰๋˜๋Š” ์—ฐ์‚ฐ โ†ฉ

  2. Critical Section: ์—ฌ๋Ÿฌ ์‹คํ–‰ ์ฃผ์ฒด๊ฐ€ ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ์ฝ”๋“œ ์˜์—ญ โ†ฉ