๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ–ฅ CS/์šด์˜์ฒด์ œ

[์šด์˜์ฒด์ œ] ํ”„๋กœ์„ธ์Šค ๋™๊ธฐํ™” (1/2)

๋ณธ ๊ฒŒ์‹œ๊ธ€์€ KOCW ์ดํ™”์—ฌ์ž๋Œ€ํ•™๊ต ๋ฐ˜ํšจ๊ฒฝ ๊ต์ˆ˜๋‹˜์˜ <์šด์˜์ฒด์ œ> ๊ฐ•์˜๋ฅผ ๋“ฃ๊ณ ,
<ํ˜ผ์ž ๊ณต๋ถ€ํ•˜๋Š” ์ปดํ“จํ„ฐ๊ตฌ์กฐ + ์šด์˜์ฒด์ œ> ์ฑ…์„ ์ฐธ๊ณ ํ•˜์—ฌ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.
๊ฒŒ์‹œ๊ธ€์— ํฌํ•จ๋˜๋Š” ์ด๋ฏธ์ง€ ์ž๋ฃŒ๋Š” <์šด์˜์ฒด์ œ> ๊ฐ•์˜์— ํฌํ•จ๋œ ๊ฐ•์˜ ์ž๋ฃŒ์ž…๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ์ ‘๊ทผ ํŒจํ„ด 

ํ”„๋กœ์„ธ์Šค ๋™๊ธฐํ™”์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ธฐ์— ์•ž์„œ ์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ ๋‚ด์—์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ ‘๊ทผ๋˜๋Š” ํŒจํ„ด์— ๋Œ€ํ•ด ๋จผ์ € ์•Œ์•„๋ด…์‹œ๋‹ค.

 

๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜์–ด์žˆ๋Š” ์œ„์น˜์—์„œ ์ฝ์–ด์™€์„œ ์—ฐ์‚ฐ์„ ํ•˜๊ณ  ์ˆ˜์ •๋œ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์‹œ ๋ฐ์ดํ„ฐ์— ๋ฐ˜์˜์„ ํ•˜๊ณ , ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๋Š” Storage Box๋Š” ๊ณต์œ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋™๊ธฐํ™”(synchronization) ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

 

๊ณต์œ  ๋ฐ์ดํ„ฐ(shared data)์˜ ๋™์‹œ ์ ‘๊ทผ์€ ๋ฐ์ดํ„ฐ์˜ ๋ถˆ์ผ์น˜ ๋ฌธ์ œ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ(consistency) ์œ ์ง€๋ฅผ ์œ„ํ•ด์„œ๋Š” ํ˜‘๋ ฅ ํ”„๋กœ์„ธ์Šค ๊ฐ„์˜ ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ์ •ํ•ด์ฃผ๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜(= ํ”„๋กœ์„ธ์Šค ๋™๊ธฐํ™”)์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

Race Condition

Race Condition์ด๋ž€ ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๋“ค์ด ๋™์‹œ์— ๊ณต์œ  ๋ฐ์ดํ„ฐ๋ฅผ ์ ‘๊ทผํ•˜๋Š” ์ƒํ™ฉ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๋ ˆ์ด์Šค ์ปจ๋””์…˜์ด ๋ฐœ์ƒํ•˜๋ฉด ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์ด ๊นจ์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.(๋ฐ์ดํ„ฐ์˜ ์ตœ์ข… ์—ฐ์‚ฐ ๊ฒฐ๊ณผ๋Š” ๋งˆ์ง€๋ง‰์— ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์–ด๋–ค ํ”„๋กœ์„ธ์Šค๋ƒ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง)

 

ํ•˜๋‚˜์˜ ์ €์žฅ๊ณต๊ฐ„์„ ๊ณต์œ ํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์—ฌ๋Ÿฟ ์žˆ๋Š” ๊ฒฝ์šฐ Race Condition์˜ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Œ

OS์—์„œ Race Condition์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ

  • ์ปค๋„ ์ˆ˜ํ–‰ ์ค‘ ์ธํ„ฐ๋ŸฝํŠธ ๋ฐœ์ƒ
  • ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹œ์Šคํ…œ ์ฝœ์„ ํ•˜์—ฌ ์ปค๋„ ๋ชจ๋“œ๋กœ ์ˆ˜ํ–‰ ์ค‘์ธ๋ฐ context switch๊ฐ€ ์ผ์–ด๋‚˜๋Š” ๊ฒฝ์šฐ
  • ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์„œ์—์„œ shared memory ๋‚ด์˜ ์ปค๋„ ๋ฐ์ดํ„ฐ

Multiprocessor ํ™˜๊ฒฝ์ด ์•„๋‹ˆ๋ผ๋ฉด, ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ ํ”„๋กœ์„ธ์Šค๋Š” ์ž๊ธฐ ์ฃผ์†Œ ๊ณต๊ฐ„๋งŒ ์ ‘๊ทผํ•˜๊ธฐ ๋•Œ๋ฌธ์— race condition ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ง์ ‘ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๋Š” ๋ถ€๋ถ„์€ ์‹œ์Šคํ…œ ์ฝœ์„ ํ†ตํ•ด ์šด์˜์ฒด์ œ์— ์š”์ฒญํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ, ์ปค๋„์˜ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ฒŒ ๋˜๋Š”๋ฐ OS ์ปค๋„ ์ฝ”๋“œ๋Š” ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. (์ปค๋„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋„์ค‘ ๋‹ค๋ฅธ ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋“ค์–ด์™€ ๋‹ค๋ฅธ ๋ฃจํ‹ด์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋  ๊ฒฝ์šฐ race condition์˜ ๊ฐ€๋Šฅ์„ฑ)

1. ์ปค๋„  ์ˆ˜ํ–‰ ์ค‘ ์ธํ„ฐ๋ŸฝํŠธ ๋ฐœ์ƒ

 

์œ„์˜ ๊ทธ๋ฆผ์€ ์ปค๋„๋ชจ๋“œ running ์ค‘ interrupt๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์ธํ„ฐ๋ŸฝํŠธ ์ฒ˜๋ฆฌ๋ฃจํ‹ด์ด ์ˆ˜ํ–‰๋˜๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

์–‘์ชฝ ๋‹ค ์ปค๋„ ์ฝ”๋“œ์ด๋ฏ€๋กœ ์ปค๋„ ์ฃผ์†Œ ๊ณต๊ฐ„์„ ๊ณต์œ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

๊ณ ๊ธ‰ ์–ธ์–ด๋กœ ๋œ ์ฝ”๋“œ ํ•œ์ค„์ด ๋ณดํ†ต CPU ๋‚ด๋ถ€์—์„œ๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ instruction์„ ํ†ตํ•ด ์‹คํ–‰์ด ๋ฉ๋‹ˆ๋‹ค. 

ex) count ๋ผ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ณ€์ˆ˜๊ฐ’์„ 1 ์ฆ๊ฐ€ ์‹œํ‚จ๋‹ค.

  • ๋ฉ”๋ชจ๋ฆฌ ๋ณ€์ˆ˜ ๊ฐ’์„ CPU ๋ ˆ์ง€์Šคํ„ฐ๋กœ ๋ถˆ๋Ÿฌ๋“ค์ธ๋‹ค.
  • ๋ ˆ์ง€์Šคํ„ฐ ๊ฐ’ 1์ฆ๊ฐ€ ์‹œํ‚จ๋‹ค.
  • ๋ ˆ์ง€์Šคํ„ฐ์˜ ๊ฐ’์„ ๋‹ค์‹œ ๋ฉ”๋ชจ๋ฆฌ์˜ ๋ณ€์ˆ˜ ์œ„์น˜์— ์“ด๋‹ค.

์œ„์˜ ๊ทธ๋ฆผ์˜ ์˜ˆ์‹œ๋กœ count ๊ฐ’์˜ ๋ณ€ํ™”๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค!

๋งŒ์•ฝ ๋ ˆ์ง€์Šคํ„ฐ๋กœ ๋ถˆ๋Ÿฌ๋“ค์ธ ๋‹ค์Œ, ๋ ˆ์ง€์Šคํ„ฐ ๊ฐ’์„ 1 ์ฆ๊ฐ€ ์‹œํ‚ค๋Š” ์ž‘์—… ์ง„ํ–‰ ์ค‘์— ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด, ์ด ์ž‘์—…์€ ์ž ์‹œ ๋ฉˆ์ถ”๊ณ  ์ธํ„ฐ๋ŸฝํŠธ ์ฒ˜๋ฆฌ ๋ฃจํ‹ด์œผ๋กœ ๋„˜์–ด๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ธํ„ฐ๋ŸฝํŠธ ์ฒ˜๋ฆฌ(count--)๊ฐ€ ๋‹ค ๋˜๋ฉด ๋‹ค์‹œ count++์˜ context๋กœ ๋Œ์•„์˜ค๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋•Œ count๊ฐ’์€ 1์ฆ๊ฐ€, 1๊ฐ์†Œ ์ž‘์—…์„ ์ฐจ๋ก€๋กœ ์ง„ํ–‰ํ–ˆ์œผ๋‹ˆ ์›๋ž˜์˜ ๊ฐ’๊ณผ ๋™์ผํ•ด์•ผ๊ฒ ์ฃ ? ํ•˜์ง€๋งŒ count--์˜ ์ž‘์—…์€ ๋ฐ˜์˜์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (๋‹ค์‹œ ์›๋ž˜ context๋กœ ๋Œ์•„์™”์„ ๋•Œ ์ด์ „์— ์ €์žฅํ•ด๋‘์—ˆ๋˜ ๊ฐ’(1์ฆ๊ฐ€์‹œํ‚ค๊ธฐ ์ „ ๊ฐ’)์—์„œ count++ ์˜ ์ž‘์—…์„ ๋งˆ๋ฌด๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ)

 

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

2. ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹œ์Šคํ…œ ์ฝœ์„ ํ•˜์—ฌ ์ปค๋„ ๋ชจ๋“œ๋กœ ์ˆ˜ํ–‰ ์ค‘์ธ๋ฐ context switch๊ฐ€ ์ผ์–ด๋‚˜๋Š” ๊ฒฝ์šฐ

์œ„์˜ ๊ทธ๋ฆผ์—์„œ ์‹œ์Šคํ…œ ์ฝœ์— ์˜ํ•ด ์œ ์ €๋ชจ๋“œ์™€ ์ปค๋„๋ชจ๋“œ๊ฐ€ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ์‹คํ–‰๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์‚ฌ์šฉ์ž ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹œ์Šคํ…œ ์ฝœ์„ ํ•˜์—ฌ ์ปค๋„ ๋ชจ๋“œ๋กœ ํ”„๋กœ์„ธ์Šค ์‹คํ–‰์ค‘์— timer interrupt (CPU ํ• ๋‹น์‹œ๊ฐ„์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ)๊ฐ€ ๊ฑธ๋ฆฌ๊ฒŒ ๋˜๋ฉด?

์œ„์˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ CPU ์ œ์–ด๊ถŒ์ด ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์—๊ฒŒ ๋„˜์–ด๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ count++ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€๋งŒ, CPU์ œ์–ด๊ถŒ์ด ๋‹ค์‹œ PA์—๊ฒŒ๋กœ ๋Œ์•„๊ฐ€๊ฒŒ ๋˜๋ฉด PA๋Š” CPU ์ œ์–ด๊ถŒ์„ ๋„˜๊ฒจ์ค„๋•Œ์˜ context์—์„œ ์ž‘์—…์„ ์ด์–ด์„œ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ๊ณผ์ ์œผ๋กœ PA๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” count++ ๋งŒ ๋ฐ˜์˜๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 

 

์ด๋Ÿฐ ๊ฒฝ์šฐ๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ปค๋„๋ชจ๋“œ์— ์žˆ๋‹ค๋ฉด CPU ํ• ๋‹น์‹œ๊ฐ„์ด ๋๋‚˜๋”๋ผ๋„ CPU๋ฅผ preempt ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์ปค๋„๋ชจ๋“œ์—์„œ ์œ ์ €๋ชจ๋“œ๋กœ ๋น ์ ธ๋‚˜์˜ฌ๋•Œ CPU๋ฅผ ๋นผ์•—๊ธฐ)

3. ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์„œ์—์„œ shared memory ๋‚ด์˜ ์ปค๋„ ๋ฐ์ดํ„ฐ

CPU๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ธ ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์„œ ํ™˜๊ฒฝ์˜ ๊ฒฝ์šฐ ์œ„์—์„œ์˜ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•์ด์—ˆ๋˜ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋ง‰๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

 

๋ฌธ์ œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:

1. ์ปค๋„์„ ์ ‘๊ทผํ•˜๋Š” CPU๊ฐ€ ๋งค์ˆœ๊ฐ„ ํ•˜๋‚˜๋งŒ ์žˆ๋„๋ก ์ปค๋„ ์ „์ฒด๋ฅผ lock์œผ๋กœ ๋ง‰๊ณ  ๋น ์ ธ๋‚˜์˜ฌ ๋•Œ lock์„ ํ’€์–ด์ฃผ๋Š” ๋ฐฉ๋ฒ• (๋น„ํšจ์œจ์ )

2. ๊ณต์œ  ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ๋•Œ ๊ทธ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ lock / unlock ์„ ๊ฑธ์–ด์„œ ํ”„๋กœ์„ธ์„œ์˜ ์ ‘๊ทผ์„ ์ œ์–ดํ•˜๋Š” ๋ฐฉ๋ฒ• (ํšจ์œจ์ )

Critical Section (์ž„๊ณ„๊ตฌ์—ญ)

Critical Section: ๊ณต์œ ๋ฐ์ดํ„ฐ๋ฅผ ์ ‘๊ทผํ•˜๋Š” ์ฝ”๋“œ

๊ฐ ํ”„๋กœ์„ธ์Šค์˜ code segment์—๋Š” ๊ณต์œ  ๋ฐ์ดํ„ฐ๋ฅผ ์ ‘๊ทผํ•˜๋Š” ์ฝ”๋“œ์ธ critical section์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

n๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ณต์œ  ๋ฐ์ดํ„ฐ๋ฅผ ๋™์‹œ์— ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ์›ํ•˜๋Š” ๊ฒฝ์šฐ, ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ critical section์— ์žˆ์„ ๋•Œ ๋‹ค๋ฅธ ๋ชจ๋“  ํ”„๋กœ์„ธ์Šค๋Š” critical section์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

Critical-Section Problem - ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ critical section์— ์žˆ๋‹ค๋ฉด ๋™๊ธฐํ™” ๋ฌธ์ œ ๊ฐ€๋Šฅ์„ฑ

ํ•ด๊ฒฐ์ฑ… 1:  Lock (๋ฎคํ…์Šค ๋ฝ)

๊ฐ€์ •

  • ๋‘ ๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •(P0, P1)
  • ํ”„๋กœ์„ธ์Šค๋“ค์˜ ์ผ๋ฐ˜์ ์ธ ๊ตฌ์กฐ
do {
    entry section // lock
    critical section
    exit section // unlock
    remainder section
} while(1);
  • ํ”„๋กœ์„ธ์Šค๋“ค์€ ์ˆ˜ํ–‰์˜ ๋™๊ธฐํ™”(synchronize)๋ฅผ ์œ„ํ•ด ๋ช‡๋ช‡ ๋ณ€์ˆ˜(synchronization variable)๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ”„๋กœ๊ทธ๋žจ์  ํ•ด๊ฒฐ๋ฒ•์˜ ์ถฉ์กฑ์กฐ๊ฑด

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

Algorithm 1

- synchronization variable: turn

int turn = 0; 
// turn ์ด i ์ด๋ฉด Pi ๊ฐ€ critical section ์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ์Œ

- Process P0

do {
    while (turn != 0); // turn ์ด 0 ์ด ์•„๋‹ˆ๋ฉด turn ์ฒดํฌํ•˜๋ฉฐ ๋ฌดํ•œ๋ฃจํ”„ ๋Œ€๊ธฐ
    critical section
    turn = 1; // critical section ๋‚˜์˜ฌ ๋•Œ ์ƒ๋Œ€๋ฐฉ์˜ ์ฐจ๋ก€๋กœ ๋„˜๊ฒจ์คŒ
    remainder section
} while(1);
  • mutual exclusion ์กฐ๊ฑด ์ถฉ์กฑO / but progress ์กฐ๊ฑด ์ถฉ์กฑX
  • ๋™์‹œ ์ ‘๊ทผ์€ ์ผ์–ด๋‚˜์ง€ ์•Š์ง€๋งŒ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ”๋‹ค ๋‚˜์™€์•ผ๋งŒ ์ฐจ๋ก€๊ฐ€ ๋Œ์•„์˜ด

Algorithm 2

- synchronization variable: flag

boolean flag[2] = { false }; // flag [i] == true ์ด๋ฉด Pi ๊ฐ€ critical section ์— ์ ‘๊ทผํ•  ์ค€๋น„์™„๋ฃŒ๋œ ๊ฒƒ

- Process P0

do {
    flag[i] = true; // ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐ€๊ณ ์ž ํ•˜๋Š” ์˜์‚ฌ ํ‘œ์‹œ
    while (flag[j]); // ์ƒ๋Œ€๋ฐฉ์˜ flag ์ฒดํฌ (์ƒ๋Œ€๋ฐฉ์ด ์ž„๊ณ„๊ตฌ์—ญ์— ์žˆ๋‹ค๋ฉด(=true) ๋Œ€๊ธฐ)
    critical section
    flag[i] = false; // ๋‚˜์˜ฌ ๋•Œ false๋กœ ๋ฐ”๊ฟ”์คŒ(unlock)
    remainder section
} while(1);
  • mutual exclusion ์กฐ๊ฑด ์ถฉ์กฑO / but progress ์กฐ๊ฑด ์ถฉ์กฑX
  • ๋งŒ์•ฝ ์ž„๊ณ„๊ตฌ์—ญ ๋“ค์–ด๊ฐ€๋ ค๊ณ  flag๋ฅผ true๋กœ ๋ฐ”๊พผ ์ƒํƒœ์—์„œ CPU ๋นผ์•—๊ธด๋‹ค๋ฉด ์ž„๊ณ„๊ตฌ์—ญ์— ์•„๋ฌด๋„ ์—†๋Š”๋ฐ true ์ƒํƒœ์ธ ๊ฒƒ
  • ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋Š” ์ž„๊ณ„๊ตฌ์—ญ์— ๋ˆ„๊ฐ€ ์žˆ๋‹ค๊ณ  ํŒ๋‹จํ•ด์„œ ๊ณ„์† ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ƒํ™ฉ์ด ์ƒ๊น€ -> ์•„๋ฌด๋„ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์Œ

Algorithm 3 (Peterson's Algorithm) 

- synchronization variable: turn, flag ๋‘˜๋‹ค ์‚ฌ์šฉ

do {
    flag[i] = true; // enter ์˜์‚ฌ ํ‘œํ˜„ (flag true๋กœ ๋ณ€๊ฒฝ)
    turn = j; // ์ž„๊ณ„๊ตฌ์—ญ ๋“ค์–ด๊ฐ€๊ธฐ ์ „์— turn ๋ณ€์ˆ˜ ๋ณ€๊ฒฝ (turn ์ƒ๋Œ€๋ฐฉ์œผ๋กœ ์„ธํŒ…)
    while (flag[j] && turn == j); // ์ƒ๋Œ€๋ฐฉ์˜ flag, turn ์ฒดํฌ (turn์ด ์ƒ๋Œ€๋ฐฉ && flag๋„ true์ด๋ฉด ๊ธฐ๋‹ค๋ฆผ) 
    critical section
    flag[i] = false; // ๋‚˜์˜ฌ ๋•Œ unlock
    remainder section
} while(1);
  • ๋ณ€์ˆ˜๋ฅผ ๋‘๊ฐœ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ค‘๊ฐ„ ์–ด๋””์—์„œ CPU๋ฅผ ๋นผ์•—๊ธด๋‹ค ํ•˜๋”๋ผ๋„ ๋ชจ๋“  ์กฐ๊ฑด ์ถฉ์กฑํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜
  • ํ•˜์ง€๋งŒ Busy Waiting(= spin lock) ์ด๋ผ๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Œ - ๊ณ„์† CPU ์™€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์“ฐ๋ฉด์„œ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋จ(๋น„ํšจ์œจ์ )
  • ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ critical section ์— ๋“ค์–ด๊ฐ€์žˆ์œผ๋ฉด ๋ณธ์ธ์˜ CPU ํ• ๋‹น์‹œ๊ฐ„ ๋™์•ˆ ๊ณ„์† while ๋ฌธ์„ ๋Œ๋ฉด์„œ critical section ์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š”์ง€ ์ฒดํฌํ•จ. but ์ƒ๋Œ€๋ฐฉ์ด CPU๋ฅผ ์žก๊ธฐ ์ „์—๋Š” ์ฒดํฌํ•˜๋Š” ๊ฐ’์ด ๋ฐ”๋€Œ์ง€ ์•Š์Œ 

Synchronization Hardware

ํ”„๋กœ์„ธ์Šค ๋™๊ธฐํ™” ๋ฌธ์ œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ฐ๋Š” ๊ฒƒ์ด ํ•˜๋‚˜์˜ instruction ์œผ๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ์ง€ ์•Š์•„์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

ํ•˜๋“œ์›จ์–ด์ ์œผ๋กœ Test & modify๋ฅผ atomicํ•˜๊ฒŒ(๋™์‹œ์—) ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•œ๋‹ค๋ฉด ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋Š” ๊ฐ„๋‹จํžˆ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

- synchronization variable: lock

boolean lock = false;
do {
    while (Test_and-Set(lock)); // ์›๋ž˜ ๊ฐ’ ์ฝ์–ด๋‚ด๊ณ (lock ์ฒดํฌ) ๊ทธ ์ž๋ฆฌ์— true๋กœ ์„ธํŒ…
    critical section
    lock = false; // ๋‚˜์˜ฌ ๋•Œ unlock
    remainder section
} while(1);

ํ•ด๊ฒฐ์ฑ… 2: Semaphore(์„ธ๋งˆํฌ์–ด)

์„ธ๋งˆํฌ์–ด๋Š” ์ผ์ข…์˜ ์ถ”์ƒ์ž๋ฃŒํ˜•(๋…ผ๋ฆฌ์ ์œผ๋กœ ์ •์˜ํ•˜๋Š” ๊ฒƒ. ์‹ค์ œ ์ปดํ“จํ„ฐ์—์„œ ๊ตฌํ˜„๋˜๋Š” ๊ฒƒ๊ณผ ๋ณ„๊ฐœ)์ž…๋‹ˆ๋‹ค.

ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ critical section ์— ๋“ค์–ด๊ฐ€๋Š” ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ์‹ ๊ฒฝ์“ฐ๊ธด ํž˜๋“œ๋‹ˆ ์ถ”์ƒ์ž๋ฃŒํ˜•(ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋กœ ์ด๋ฃจ์–ด์ง„ ๋…ผ๋ฆฌ์ž๋ฃŒํ˜•)์œผ๋กœ ์—ฐ์‚ฐ์„ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์„ธ๋งˆํฌ์–ด๋Š” ๊ณต์œ  ์ž์›์ด ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ๋Š” ์ƒํ™ฉ์—์„œ๋„ ์ ์šฉ์ด ๊ฐ€๋Šฅํ•œ ๋™๊ธฐํ™” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. (cf. ๋ฎคํ…์Šค ๋ฝ์€ ํ•˜๋‚˜์˜ ๊ณต์œ ์ž์› ๋Œ€์ƒ)

์„ธ๋งˆํฌ์–ด์˜ ์ข…๋ฅ˜

1. counting semaphore

- ์ž์›์˜ ๊ฐœ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ -> 0 ์ด์ƒ์˜ ์ •์ˆ˜๊ฐ’์„ ์‚ฌ์šฉ

 

2. binary semaphore (= mutex lock)

- 0 ๋˜๋Š” 1์˜ ๊ฐ’๋งŒ ๊ฐ€์ง

- mutual exclusion (lock / unlock) ์— ์‚ฌ์šฉํ•œ๋‹ค. (= ๋ฎคํ…์Šค ๋ฝ)

Semaphore S

- integer ๋ณ€์ˆ˜

- ์•„๋ž˜์˜ ๋‘ ๊ฐ€์ง€ atomic ์—ฐ์‚ฐ(P, V)์— ์˜ํ•ด์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ

 

P(S): while (S <= 0) do no-op
      S--;

 

V(S): S++;

 

  • P ์—ฐ์‚ฐ 
    • S๊ฐ’์ด 0์ดํ•˜(=์“ธ ์ˆ˜ ์žˆ๋Š”์ž์›์ด ์—†์Œ)์ธ ๋™์•ˆ while๋ฌธ ๋Œ๋ฉด์„œ wait
    • S๊ฐ’์ด ์–‘์ˆ˜๊ฐ€ ๋˜๋ฉด(= ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ž์›์„ ๋‚ด์–ด๋†“์œผ๋ฉด) ๊ทธ ๋•Œ S--, ์ž์› ํš๋“, lock
  • V ์—ฐ์‚ฐ
    • ๊ณต์œ  ์ž์› ๋ฐ˜๋‚ฉ, S++, unlock
// Synchronization variable
Semaphore mutex;

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

์„ธ๋งˆํฌ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด, ์„ธ๋งˆํฌ์–ด ๋ณ€์ˆ˜์ธ mutex๋ฅผ 1๋กœ ๋†“๊ณ  lock์„ ๊ฑธ๋•Œ(= ์ž„๊ณ„๊ตฌ์—ญ์— ๋“ค์–ด๊ฐˆ ๋•Œ) P์—ฐ์‚ฐ, ํ’€ ๋•Œ(์ž„๊ณ„๊ตฌ์—ญ์—์„œ ๋น ์ ธ๋‚˜์˜ฌ๋•Œ) V์—ฐ์‚ฐ์„ ํ•ด์ฃผ๋ฉด ์ž„๊ณ„๊ตฌ์—ญ ๋ฌธ์ œ๊ฐ€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ busy-waiting (= spin lock)๋ฌธ์ œ๋Š” ์—ฌ์ „ํžˆ ๋ฐœ์ƒํ•˜๋Š”๋ฐ, ์ด๋Š” ํšจ์œจ์ ์ด์ง€ ๋ชปํ•˜๋ฏ€๋กœ Block & Wakeup (= sleep lock) ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Block & Wakeup Implementation

์„ธ๋งˆํฌ์–ด ์ •์˜

- S: ์„ธ๋งˆํฌ์–ด ๋ณ€์ˆ˜

- L: ํ”„๋กœ์„ธ์Šค ๋Œ€๊ธฐ ํ

- block: ์ปค๋„์€ block์„ ํ˜ธ์ถœํ•œ ํ”„๋กœ์„ธ์Šค๋ฅผ suspend ์‹œํ‚ด. ์ด ํ”„๋กœ์„ธ์Šค์˜ PCB๋ฅผ ์„ธ๋งˆํฌ์–ด์— ๋Œ€ํ•œ wait queue์— ๋„ฃ์Œ

- wakeup(P): block๋œ ํ”„๋กœ์„ธ์Šค P๋ฅผ wakeup ์‹œํ‚ด. ์ด ํ”„๋กœ์„ธ์Šค์˜ PCB๋ฅผ ready queue๋กœ ์˜ฎ๊น€

 

์—ฐ์‚ฐ

P(S)

S.value--;
if (S.value < 0) { // ๊ณต์œ  ์ž์› ์ ‘๊ทผ ๋ถˆ๊ฐ€ 
    add this process to S.L;
    block(); // suspend
}
V(S)

S.value++;
if (S.value <= 0) { // ์ž์›์„ ๋‚ด๋†จ๋Š”๋ฐ ๊ธฐ๋‹ค๋ฆฌ๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ์Œ
    remove a process P from S.L;
    wakeup(P); // wakeup
}

ํ”„๋กœ์„ธ์Šค ์ž์ฒด๋ฅผ blocked ์‹œ์ผœ์„œ ํ•ด๋‹น ํ”„๋กœ์„ธ์Šค๊ฐ€ CPU๋ฅผ ์•„์˜ˆ ๋ฐ˜๋‚ฉํ•˜๊ณ  ์ž ๋“ค์–ด ์žˆ๋‹ค๊ฐ€ ๊ณต์œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ CPU๋ฅผ ๋‚ด๋†“์œผ๋ฉด ๊ทธ ๋•Œ ready queue์— ๋“ค์–ด๊ฐ€์„œ CPU๋ฅผ ์–ป๋Š” ๋ฐฉ์‹(์“ธ๋ฐ์—†์ด CPU๋ฅผ ์žก๊ณ ์žˆ์œผ๋ฉด์„œ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์Œ)์ž…๋‹ˆ๋‹ค.

block & wakeup ๋ฐฉ์‹์˜ ๊ฒฝ์šฐ, ํ”„๋กœ์„ธ์Šค๋ฅผ ์žฌ์šฐ๊ณ  ๊นจ์šฐ๋Š”๋ฐ์— ๋Œ€ํ•œ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ critical section ์˜ ๊ธธ์ด๊ฐ€ ๋งค์šฐ ์งง์€ ๊ฒฝ์šฐ busy-wait ๊ฐ€ ๋‚˜์„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” block & wakeup ์ด ๋” ํšจ์œจ์ (CPU ์ด์šฉ๋ฅ  ์ธก๋ฉด์—์„œ)์ž…๋‹ˆ๋‹ค.

์„ธ๋งˆํฌ์–ด์˜ ๋ฌธ์ œ์ : Deadlock & Starvation

๋งŒ์•ฝ ํ”„๋กœ์„ธ์Šค๊ฐ€ S, Q์ž์› ๋ชจ๋‘ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค๋ฉด,

๋‘ ๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์„œ๋กœ์— ์˜ํ•ด ์˜์›ํžˆ S, Q ์ž์› ๋‘ ๊ฐœ ๋ชจ๋‘๋ฅผ ํ•œ๊บผ๋ฒˆ์— ํš๋“ํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. (Deadlock)

ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ•˜๋‚˜์˜ ์ž์›์„ ์„ ์ ํ•œ ์ฑ„๋กœ ๋‹ค๋ฅธ ์ž์›์„ ์–ป๊ธฐ ์œ„ํ•ด ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋˜๋Š”๋ฐ, ํ•˜๋‚˜์”ฉ ์„ ์ ํ•œ ์ƒํƒœ๋ผ๋ฉด ํš๋“ํ•  ์ˆ˜ ์—†๋Š” ์ž์›์„ ๋ฌดํ•œํžˆ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. (Starvation)

 

  • Deadlock: ๋‘˜ ์ด์ƒ์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์„œ๋กœ ์ƒ๋Œ€๋ฐฉ์— ์˜ํ•ด ์ถฉ์กฑ๋  ์ˆ˜ ์žˆ๋Š” event๋ฅผ ๋ฌดํ•œํžˆ ๊ธฐ๋‹ค๋ฆฌ๋Š” ํ˜„์ƒ
  • Starvation: ํ”„๋กœ์„ธ์Šค๊ฐ€ suspend๋œ ์ด์œ ์— ํ•ด๋‹นํ•˜๋Š” ์„ธ๋งˆํฌ์–ด ํ์—์„œ ๋น ์ ธ๋‚˜๊ฐˆ ์ˆ˜ ์—†๋Š” ํ˜„์ƒ. ์ผ๋ถ€ ํ”„๋กœ์„ธ์Šค์˜ ๊ณต์œ  ์ž์›์„ ๋…์ ์œผ๋กœ ์–ด๋–ค ํ”„๋กœ์„ธ์Šค๋Š” ์˜์›ํžˆ ์ž์›์„ ์–ป์ง€ ๋ชปํ•ด์„œ ์‹คํ–‰๋˜์ง€ ๋ชปํ•จ. (indefinite blocking)
  • Deadlock๋„ Starvation์˜ ์ผ์ข…์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ์Œ