๐Ÿ‘€ Process Synchronization ๋ฌธ์ œ

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

๐Ÿ”ธ Race condition

  • ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๋“ค์ด ๋™์‹œ์— ๊ณต์œ  ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ์ƒํ™ฉ
  • ๋ฐ์ดํ„ฐ์˜ ์ตœ์ข… ์—ฐ์‚ฐ ๊ฒฐ๊ณผ๋Š” ๋งˆ์ง€๋ง‰์— ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฌ ํ”„๋กœ์„ธ์Šค์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง
  • Race condition์„ ๋ง‰๊ธฐ ์œ„ํ•ด concurrent process(๋™์‹œ ์ ‘๊ทผ)๋Š” ๋™๊ธฐํ™”(synchronize)๋˜์–ด์•ผ ํ•œ๋‹ค.


Race Condition์ด ๋ฐœ์ƒํ•˜๋Š” ์ƒํ™ฉ

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

  • ์ปค๋„ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋„์ค‘์— ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ์ƒ๊ธด ๊ฒฝ์šฐ
  • ํ•ด๊ฒฐ์ฑ… : ๋จผ์ € ์ž‘์—… ์ค‘์ด๋˜ ์ปค๋„ ์ฝ”๋“œ์˜ ์ž‘์—…์ด ๋๋‚˜๊ธฐ ์ „ ๊นŒ์ง€๋Š” ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.

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

  • A ํ”„๋กœ์„ธ์Šค๊ฐ€ PC๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ๋„์ค‘์— ๋‹ค๋ฅธ ์ปค๋„ ์ฝ”๋“œ B์—๊ฒŒ CPU๋ฅผ ๋บ๊ฒผ๋‹ค๊ฐ€ ๋บ์–ด๊ฐ„ ์ชฝ์˜ ์ž‘์—…์ด ๋๋‚œ ํ›„ ๋‹ค์‹œ ๋Œ๋ ค ๋ฐ›์œผ๋ฉด A๋Š” B๊ฐ€ ์ฆ๊ฐ€์‹œํ‚ค๊ธฐ ์ „์˜ PC ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— A๊ฐ€ ์ฆ๊ฐ€์‹œํ‚ค๋Š” PC๋Š” ์ •ํ™•ํ•œ ๊ฐ’์œผ๋กœ ์ฆ๊ฐ€๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ํ•ด๊ฒฐ์ฑ… : ์ปค๋„ ๋ชจ๋“œ์—์„œ ์ˆ˜ํ–‰ ์ค‘์ผ ๋•Œ๋Š” CPU๋ฅผ preemptํ•˜์ง€ ์•Š๊ณ  ์ปค๋„ ๋ชจ๋“œ์—์„œ ์‚ฌ์šฉ์ž ๋ชจ๋“œ๋กœ ๋Œ์•„๊ฐˆ ๋•Œ preemptํ•œ๋‹ค.

3. Multiprocessor์—์„œ shared memory ๋‚ด์˜ ์ปค๋„ ๋ฐ์ดํ„ฐ

  • ์œ„ ๊ฒฝ์šฐ๋“ค์€ ๊ฐ™์€ CPU ๋‚ด์—์„œ๋งŒ ํ•  ์ˆ˜ ์žˆ๋Š” ๋™์ž‘๋“ค์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ€ํ‹ฐ ํ”„๋กœ์„ธ์„œ ํ™˜๊ฒฝ์—์„œ๋Š” ์ ์šฉ์ด ์–ด๋ ต๋‹ค.
  • ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๋“ค์ด ํ•˜๋‚˜์˜ ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ์— ์ ‘๊ทผํ•ด์•ผ ํ•  ๋•Œ ๊ฐ๊ฐ์˜ CPU์—์„œ ๋™์‹œ์— ์ ‘๊ทผํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ•ด๊ฒฐ์ฑ… 1 : ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ CPU๋งŒ์ด ์ปค๋„์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•
  • ํ•ด๊ฒฐ์ฑ… 2 : ์ปค๋„ ๋‚ด๋ถ€์— ์žˆ๋Š” ๊ฐ ๊ณต์œ  ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ๋•Œ๋งˆ๋‹ค ๊ทธ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ lock/unlock์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•


The Critical-Section Problem

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

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

  • Mutual Exclusion(์ƒํ˜ธ ๋ฐฐ์ œ/๋ฐฐํƒ€์  ์ ‘๊ทผ)
    • ํ”„๋กœ์„ธ์Šค Pirk critical section ๋ถ€๋ถ„์„ ์ˆ˜ํ–‰ ์ค‘์ด๋ฉด ๋‹ค๋ฅธ ๋ชจ๋“  ํ”„๋กœ์„ธ์Šค๋“ค์€ ๊ทธ๋“ค์˜ critical section์— ๋“ค์–ด๊ฐ€๋ฉด ์•ˆ ๋œ๋‹ค.
  • Progress(์ง„ํ–‰)
    • ์•„๋ฌด๋„ critical section์— ์žˆ์ง€ ์•Š์€ ์ƒํƒœ์—์„œ critical section์— ๋“ค์–ด๊ฐ€๊ณ ์ž ํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ์œผ๋ฉด critical section์— ๋“ค์–ด๊ฐ€๊ฒŒ ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.
  • Bounded Waiting(์œ ํ•œ ๋Œ€๊ธฐ)
    • ํ”„๋กœ์„ธ์Šค๊ฐ€ critical section์— ๋“ค์–ด๊ฐ€๋ ค๊ณ  ์š”์ฒญํ•œ ํ›„๋ถ€ํ„ฐ ๊ทธ ์š”์ฒญ์ด ํ—ˆ์šฉ๋  ๋•Œ๊นŒ์ง€ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋“ค์ด critical section์— ๋“ค์–ด๊ฐ€๋Š” ํšŸ์ˆ˜์— ํ•œ๊ณ„๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
    • ๋ฌดํ•œ๋Œ€๋กœ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ฒŒ ํ•ด์„œ starvation์„ ๋ฐฉ์ง€
  • ๊ฐ€์ •
    • ๋ชจ๋“  ํ”„๋กœ์„ธ์Šค์˜ ์ˆ˜ํ–‰ ์†๋„๋Š” 0๋ณด๋‹ค ํฌ๋‹ค.
    • ํ”„๋กœ์„ธ์Šค๋“ค ๊ฐ„์˜ ์ƒ๋Œ€์ ์ธ ์ˆ˜ํ–‰ ์†๋„๋Š” ๊ฐ€์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.

๊ธฐ๋ณธ์ ์ธ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

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

Algorithm 1

int turn;   /* ๋ˆ„๊ตฌ ์ฐจ๋ก€์ธ์ง€ ํ‘œ์‹œํ•  ๋ณ€์ˆ˜.  Synchronization variable */
initially turn = 0;

do {
    while (turn != 0);  /* ๋‚ด ํ„ด์ด ์•„๋‹Œ ๋™์•ˆ ๋Œ€๊ธฐ */
    critical section
    turn = 1;   /* ์ƒ๋Œ€ํŽธ์œผ๋กœ ํ„ด ๋„˜๊น€ */
    remainder section
} while (1);
  • ์œ„ ์ฝ”๋“œ๋Œ€๋กœ๋งŒ ์ง„ํ–‰๋˜๋ฉด ๋ฌธ์ œ๊ฐ€ ์—†์–ด ๋ณด์ด์ง€๋งŒ ๋ฐ˜๋“œ์‹œ ์ƒ๋Œ€ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋“ค์–ด์™€์„œ turn์„ ๋ฐ”๊ฟ” ์ฃผ์–ด์•ผ๋งŒ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ critical section์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งŒ์•ฝ A ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋” ๋นˆ๋ฒˆํ•˜๊ฒŒ critical section์— ๋“ค์–ด๊ฐ€์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ B ํ”„๋กœ์„ธ์Šค๋Š” ์ƒ๋Œ€์ ์œผ๋กœ ๋œ ๋“ค์–ด๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— turn์ด ๋ฐ”๋€Œ์ง€ ์•Š์•„ A ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ด ์ƒ๊ธด๋‹ค.

Algorithm 2

boolean flag[2];    /* critical section์— ๋“ค์–ด๊ฐ€๊ณ ์ž ํ•˜๋Š” ์˜์ค‘์„ ํ‘œ์‹œํ•˜๋Š” flag */
initially flag[๋ชจ๋‘] = false; /* ์ฒ˜์Œ์—” critical section์— ์•„๋ฌด๋„ ์—†์Œ */

do {
    flag[i] = true;     /* ์ง„์ž… ํ‘œ์‹œ */
    while (flag[j]);    /* ์ƒ๋Œ€ ํ”„๋กœ์„ธ์Šค๋„ ์ง„์ž…ํ•ด ์žˆ์œผ๋ฉด ๋Œ€๊ธฐ */
    critical section
    flag[i] = false;    /* ๋‚˜์™”๋‹ค๊ณ  ํ‘œ์‹œ */
    remainder section
} while (1);
  • ์œ„ ์ฝ”๋“œ์—์„œ๋Š” ๋งŒ์•ฝ A ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ฒซ๋ฒˆ์งธ ์ค„๋งŒ ์‹คํ–‰ํ•˜๊ณ  CPU๋ฅผ ๋บ๊ธด ๊ฒฝ์šฐ ์ƒ๋Œ€ ํ”„๋กœ์„ธ์Šค๋„ ์ฒซ๋ฒˆ์งธ ์ค„์„ ์‹คํ–‰ํ•˜๊ณ  ๋‘๋ฒˆ์งธ ์ค„์—์„œ ๋Œ€๊ธฐํ•˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค. ์ฆ‰ ๋‘˜ ๋‹ค ๋ฌดํ•œํžˆ ๋Œ€๊ธฐํ•˜๊ฒŒ ๋œ๋‹ค.

Algorithm 3 (Petersonโ€™s Algorithm)

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

ํ•˜๋“œ์›จ์–ด์ ์œผ๋กœ ํ•ด๊ฒฐํ•˜๊ธฐ

  • Instruction ํ•˜๋‚˜๋กœ Synchronization variable ์ฝ๊ธฐ์™€ ์“ฐ๊ธฐ๋ฅผ ๋™์‹œ์— ์‹คํ–‰ํ•˜๋ฉด ์œ„์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ํ•ด๊ฒฐํ•˜๊ณ ์ž ํ–ˆ๋˜ ๋ฌธ์ œ๋“ค์„ ๊ฐ„๋‹จํžˆ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.
boolean lock = false;

do {
    while (Test_and_set(lock); /* lock์ด ๊ฑธ๋ ค์žˆ๋‹ค๋ฉด lock์„ ๊ฑธ๊ณ  ๊ธฐ๋‹ค๋ฆด ๊ฒƒ์ด๊ณ  ๊ฑธ๋ ค์žˆ์ง€ ์•Š๋‹ค๋ฉด lock์„ ๊ฑธ๊ณ  ๋“ค์–ด๊ฐˆ ๊ฒƒ์ž„ */
    critical section
    lock = false;
    remainder section
} while (1);



Semaphores

  • ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋งค๋ฒˆ ์•ž์˜ ์ž‘์—…๋“ค์„ ํ•˜๋ ค๋ฉด ๊ท€์ฐฎ์œผ๋‹ˆ๊นŒ ๊ทธ ์ž‘์—…๋“ค์„ ์ถ”์ƒํ™”์‹œํ‚จ ๊ฒƒ
  • integer variable ํ˜•ํƒœ๋กœ ์ž์›์˜ ๊ฐฏ์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  • ์•„๋ž˜์˜ ๋‘ ๊ฐ€์ง€ atomic ์—ฐ์‚ฐ์— ์˜ํ•ด์„œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
/* P(S) : ๊ณต์œ  ๋ฐ์ดํ„ฐ๋ฅผ ํš๋“ํ•˜๋Š” ์—ฐ์‚ฐ */
while (S <= 0) do wait; /* ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ž์›์ด ์—†์œผ๋ฉด ๋Œ€๊ธฐ */
S--;

/* V(S) : ๊ณต์œ  ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉ ํ›„ ๋ฐ˜๋‚ฉ */
S++;

์„ธ๋งˆํฌ์–ด๋ฅผ ์ด์šฉํ•œ ์ฝ”๋“œ - Busy-wait

semaphore mutex;    /* initially 1 : 1๊ฐœ๊ฐ€ critical section์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค */

do {
    P(mutex);   /* ์ž์›์ด ๋‚จ์•„ ์žˆ์œผ๋ฉด ํ•˜๋‚˜ ๊ฐ์†Œ์‹œํ‚ค๊ณ  ์ž…์žฅ */
    critical section
    V(mutex);   /* ์ž์› ๋ฐ˜๋‚ฉ ๋ฐ ์ฆ๊ฐ€ */
    remainder section
} while (1);
  • ๋Œ€๊ธฐํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ์œผ๋ฉด ์ž์›์ด ์ƒ๊ฒผ๋Š”์ง€ ๊ณ„์† ํ™•์ธํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— busy-waitํ•˜๊ฒŒ ๋œ๋‹ค.

์„ธ๋งˆํฌ์–ด๋ฅผ ์ด์šฉํ•œ ์ฝ”๋“œ - Block & wekeup

  • ์„ธ๋งˆํฌ์–ด๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•œ๋‹ค.
typedef struct
{
    int value;          /* semaphore */
    struct process *L;  /* ํ”„๋กœ์„ธ์Šค ๋Œ€๊ธฐ์—ด */
} semaphore;
  • block๊ณผ wakeup์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ€์ •ํ•œ๋‹ค.
    • block : ์ปค๋„์€ block์„ ํ˜ธ์ถœํ•œ ํ”„๋กœ์„ธ์Šค๋ฅผ suspend ์‹œํ‚จ ํ›„ ์ด ํ”„๋กœ์„ธ์Šค์˜ PCB๋ฅผ ์„ธ๋งˆํฌ์–ด์— ๋Œ€ํ•œ ๋Œ€๊ธฐ์—ด์— ๋„ฃ์Œ
    • wakeup : block๋œ ํ”„๋กœ์„ธ์Šค๋ฅผ wakeup ์‹œํ‚จ ํ›„ ์ด ํ”„๋กœ์„ธ์Šค์˜ PCB๋ฅผ ready queue๋กœ ์˜ฎ๊น€
  • ์„ธ๋งˆํฌ์–ด ์—ฐ์‚ฐ ์ •์˜
/* P(S) */
S.value--;  /* ์ž…์žฅ ์ „์— ์ž์›์˜ ์ˆ˜๋ฅผ ๊ฐ์†Œ์‹œํ‚ด */
if (S.value < 0)    /* ํ˜„์žฌ ์“ธ ์ˆ˜ ์žˆ๋Š” ์ž์›์ด ์—†์œผ๋ฉด ๋Œ€๊ธฐ์‹œํ‚จ๋‹ค */
{
    add this process to S.L;
    block();
}

/* V(S) */
S.value++;
if (S.value <= 0)   /* P ์—ฐ์‚ฐ์—์„œ ์ž์›์„ ๋ฏธ๋ฆฌ ๊ฐ์†Œ์‹œํ‚ค๊ณ  ๋“ค์–ด๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ์ž์›์„ ๋ฐ˜๋‚ฉํ–ˆ๋Š”๋ฐ๋„ ๊ฐฏ์ˆ˜๊ฐ€ 0 ์ดํ•˜๋ผ๋ฉด ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ๋Š” ๊ฒƒ */
{
    remove a process P from S.L;
    wakeup(P);
}

๐Ÿ‘€ Busy-wait vs. Block/wakeup

  • critical section์˜ ๊ธธ์ด๊ฐ€ ๊ธด ๊ฒฝ์šฐ Block/wakeup์ด ์ ๋‹น
  • critical section์˜ ๊ธธ์ด๊ฐ€ ๋งค์šฐ ์งง์€ ๊ฒฝ์šฐ Block/wakeup ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ Busy-wait ์˜ค๋ฒ„ํ—ค๋“œ๋ณด๋‹ค ๋” ์ปค์งˆ ์ˆ˜ ์žˆ๋‹ค.
  • ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” Block/wakeup ๋ฐฉ์‹์ด ์ข‹๋‹ค.

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

  • Counting semaphore
    • ๋„๋ฉ”์ธ์ด 0 ์ด์ƒ์ธ ์ž„์˜์˜ ์ •์ˆ˜๊ฐ’
    • ์ฃผ๋กœ ๋ฆฌ์†Œ์Šค์˜ ๊ฐฏ์ˆ˜๋ฅผ ์„ธ๋Š” ๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.
  • Binary semaphore
    • 0 ๋˜๋Š” 1 ๊ฐ’๋งŒ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์„ธ๋งˆํฌ์–ด
    • ์ฃผ๋กœ mutual exclusion (lock/unlock)์— ์‚ฌ์šฉ

Deadlock and Starvation

Deadlock

  • ๋‘˜ ์ด์ƒ์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์„œ๋กœ ์ƒ๋Œ€๋ฐฉ์— ์˜ํ•ด ์ถฉ์กฑ๋  ์ˆ˜ ์žˆ๋Š” event๋ฅผ ๋ฌดํ•œํžˆ ๊ธฐ๋‹ค๋ฆฌ๋Š” ํ˜„์ƒ
  • 1๊ณผ 2 ๋‘ ๊ฐœ์˜ ์ž์›์„ ์–ป์–ด์•ผ ํ•˜๋Š” A ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ์„ ๋•Œ ๋งŒ์•ฝ A ํ”„๋กœ์„ธ์Šค๊ฐ€ 1๋ฒˆ ์ž์›๋งŒ ์–ป๊ณ  B ํ”„๋กœ์„ธ์Šค์—๊ฒŒ CPU๋ฅผ ๋บ๊ธด ํ›„ B ํ”„๋กœ์„ธ์Šค๊ฐ€ 2๋ฒˆ ์ž์›์„ ์–ป์œผ๋ฉด A ํ”„๋กœ์„ธ์Šค๋Š” CPU๋ฅผ ๋‹ค์‹œ ๋Œ๋ ค๋ฐ›์•„๋„ 2๋ฒˆ ์ž์›์„ ์–ป์ง€ ๋ชปํ•ด์„œ ๋‹ค์Œ์œผ๋กœ ์ง„ํ–‰ํ•  ์ˆ˜ ์—†๋‹ค. B ํ”„๋กœ์„ธ์Šค ๋˜ํ•œ 1๋ฒˆ ์ž์›์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ์˜์›ํžˆ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋œ๋‹ค.
  • ์ด๋Ÿฌํ•œ ํ˜„์ƒ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ž์›์„ ํš๋“ํ•˜๋Š” ์ˆœ์„œ๋ฅผ ์ •ํ•ด์ค˜์„œ 1๋ฒˆ ์ž์›์„ ๋จผ์ € ์–ป์–ด์•ผ๋งŒ 2๋ฒˆ ์ž์›์„ ์–ป์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

Starvation

  • indefinite blocking
  • ํ”„๋กœ์„ธ์Šค๊ฐ€ suspend๋œ ์ด์œ ์— ํ•ด๋‹นํ•˜๋Š” ์„ธ๋งˆํฌ์–ด ํ์—์„œ ๋น ์ ธ๋‚˜๊ฐˆ ์ˆ˜ ์—†๋Š” ํ˜„์ƒ


Classical Problems of Synchronization

๐Ÿ”ธ Bounded buffer problem

  • Producer-Consumer Problem์ด๋ผ๊ณ ๋„ ํ•˜๋ฉฐ ๋ฐ์ดํ„ฐ ์ž…๋ ฅ์„ ์œ„ํ•œ ๋ฒ„ํผ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ƒ์‚ฐ์ž์™€ ๊ทธ ๋ฒ„ํผ๋ฅผ ์ฝ์–ด์„œ ์ˆ˜์ •๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜์˜ํ•  ์†Œ๋น„์ž๋กœ ๋‚˜๋ˆ„๋Š” ๊ฐœ๋…์ด๋‹ค.
  • ์ƒ์‚ฐ์ž๋Š” ๋นˆ ๋ฒ„ํผ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ ํ›„(์—†์œผ๋ฉด ๊ธฐ๋‹ค๋ฆผ) ๊ณต์œ ๋ฐ์ดํ„ฐ์— lock์„ ๊ฑธ๊ณ  ๋ฒ„ํผ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•œ ๋‹ค์Œ lock์„ ํ’€๊ณ  ๋“  ๋ฒ„ํผ๋ฅผ ํ•˜๋‚˜ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.
  • ์†Œ๋น„์ž๋Š” ๋“  ๋ฒ„ํผ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ ํ›„(์—†์œผ๋ฉด ๊ธฐ๋‹ค๋ฆผ) ๊ณต์œ ๋ฐ์ดํ„ฐ์— lock์„ ๊ฑธ๊ณ  ๋ฒ„ํผ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊บผ๋‚ธ ๋’ค lock์„ ํ’€๊ณ  ๋นˆ ๋ฒ„ํผ๋ฅผ ํ•˜๋‚˜ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.

๊ณต์œ  ๋ฐ์ดํ„ฐ

  • ๋ฒ„ํผ ๋ฐ ๋ฒ„ํผ ์กฐ์ž‘ ๋ณ€์ˆ˜(empty/full buffer์˜ ์‹œ์ž‘ ์œ„์น˜)

๋™๊ธฐํ™” ๋ณ€์ˆ˜

  • mutual exclusion : ๊ณต์œ ๋ฐ์ดํ„ฐ์˜ mutual exclusion์„ ์œ„ํ•ด ํ•„์š”
  • resource count : ๋‚จ์€ empty/full buffer์˜ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”
/* Producer */
do {
    produce an item in x
    ...
    P(empty);
    P(mutex);
    ...
    add x to buffer
    ...
    V(mutex);
    V(full);
} while (1);

/* Consumer */
do {
    P(full);
    P(mutex);
    ...
    remove an item from buffer to y
    ...
    V(mutex);
    V(empty);
    ...
    consume the item in y
    ...
} while (1);

๐Ÿ”ธ Readers-Writers Problem

  • ํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ DB์— write ์ค‘์ผ ๋•Œ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ ‘๊ทผํ•˜๋ฉด ์•ˆ ๋จ
  • read๋Š” ๋™์‹œ์— ์—ฌ๋Ÿฟ์ด ํ•ด๋„ ๋จ
  • solution
    • Writer๊ฐ€ DB์— ์ ‘๊ทผ ํ—ˆ๊ฐ€๋ฅผ ์•„์ง ์–ป์ง€ ๋ชปํ•œ ์ƒํƒœ์—์„œ๋Š” ๋ชจ๋“  ๋Œ€๊ธฐ ์ค‘์ธ Reader๋“ค์„ ๋‹ค DB์— ์ ‘๊ทผํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.
    • Writer๋Š” ๋Œ€๊ธฐ ์ค‘์ธ Reader๊ฐ€ ํ•˜๋‚˜๋„ ์—†์„ ๋•Œ DB ์ ‘๊ทผ์ด ํ—ˆ์šฉ๋œ๋‹ค.
    • ์ผ๋‹จ Writer๊ฐ€ DB์— ์ ‘๊ทผ ์ค‘์ด๋ฉด Reader๋“ค์€ ์ ‘๊ทผ์ด ๊ธˆ์ง€๋œ๋‹ค.
    • Writer๊ฐ€ DB์—์„œ ๋น ์ ธ ๋‚˜๊ฐ€์•ผ๋งŒ Reader์˜ ์ ‘๊ทผ์ด ํ—ˆ์šฉ๋œ๋‹ค.

๊ณต์œ  ๋ฐ์ดํ„ฐ

  • DB ์ž์ฒด
  • readcount : ํ˜„์žฌ DB์— ์ ‘๊ทผ ์ค‘์ธ Reader์˜ ์ˆ˜

๋™๊ธฐํ™” ๋ณ€์ˆ˜

  • mutex : ๊ณต์œ  ๋ณ€์ˆ˜ readcount๋ฅผ ์ ‘๊ทผํ•˜๋Š” ์ฝ”๋“œ(critical section)์˜ mutual exclusion ๋ณด์žฅ์„ ์œ„ํ•ด ์‚ฌ์šฉ
  • db : Reader์™€ Writer๊ฐ€ ๊ณต์œ  DB ์ž์ฒด๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ ‘๊ทผํ•˜๋Š” ์—ญํ• 
int readcount = 0;
DB ์ž์ฒด;
semaphore mutex = 1, db = 1;

/* Writer */
P(db);
...
writing DB ...
...
V(db);

/* Reader */
P(mutex);
readcount++;
if (readcount == 1) P(db);  /* Writer ๋Œ€๊ธฐ์‹œํ‚ด */
V(mutex);
...
reading DB ...
...
P(mutex);
readcount--;
if (readcount == 0) V(db);  /* Writer ์ž…์žฅ ๊ฐ€๋Šฅ */
V(mutex);
  • ํ•˜์ง€๋งŒ ์œ„ ์ฝ”๋“œ๋Œ€๋กœ๋งŒ ํ•˜๋ฉด Reader๊ฐ€ ๊ณ„์† ๋“ค์–ด์™€์„œ Writer๊ฐ€ ์˜์›ํžˆ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—(starvation) Writer์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋†’์—ฌ์ค˜์„œ ๋„ˆ๋ฌด ์˜ค๋ž˜ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ฒŒ ํ•œ๋‹ค.

๐Ÿ”ธ Dining-Philosophers Problem

  • ๋‹ค์„ฏ ๋ช…์˜ ์ฒ ํ•™์ž๊ฐ€ ์›ํ˜• ํ…Œ์ด๋ธ”์— ์•‰์•„์„œ ์ƒ๊ฐ๊ณผ ์‹์‚ฌ๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š”๋ฐ ์ “๊ฐ€๋ฝ์ด 5๊ฐœ(2๊ฐœ ์„ธํŠธ ์•„๋‹˜)๋ฐ–์— ์—†์Œ
  • ์ฒ ํ•™์ž๋Š” ๋‚ด ์–‘ ์˜†์— ์žˆ๋Š” ์ “๊ฐ€๋ฝ์„ ์˜†์— ์žˆ๋Š” ์ฒ ํ•™์ž๋“ค์ด ์“ฐ๊ณ  ์žˆ์ง€ ์•Š์•„์•ผ ์ “๊ฐ€๋ฝ์„ ์‚ฌ์šฉํ•ด ๋ฐฅ์„ ๋จน์„ ์ˆ˜ ์žˆ๋‹ค.
  • ์ด ๋•Œ ์–ด๋–ค ์ฒ ํ•™์ž์˜ ์–‘ ์˜†์— ์žˆ๋Š” ์ฒ ํ•™์ž๋“ค์ด ๊ณ„์† ๋ฐฅ์„ ๋จน์–ด์„œ ์–ด๋–ค ์ฒ ํ•™์ž๊ฐ€ ์ “๊ฐ€๋ฝ์„ ์˜์›ํžˆ ์“ฐ์ง€ ๋ชปํ•˜๋ฉด ๊ตถ์–ด ์ฃฝ๋Š”๋‹ค๋Š”.. ๊ทธ๋Ÿฐ ๋ฌธ์ œ์ด๋‹ค.
  • ํ•ด๊ฒฐ ๋ฐฉ์•ˆ
    • 4๋ช…์˜ ์ฒ ํ•™์ž๋งŒ ํ…Œ์ด๋ธ”์— ๋™์‹œ์— ์•‰์„ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.
    • ์ “๊ฐ€๋ฝ์„ ๋‘ ๊ฐœ ๋ชจ๋‘ ์ง‘์„ ์ˆ˜ ์žˆ์„ ๋•Œ์—๋งŒ ์ “๊ฐ€๋ฝ์„ ์ง‘์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.
    • ๋น„๋Œ€์นญ : ์ง์ˆ˜(ํ™€์ˆ˜) ์ฒ ํ•™์ž๋Š” ์™ผ์ชฝ(์˜ค๋ฅธ์ชฝ) ์ “๊ฐ€๋ฝ๋ถ€ํ„ฐ ์ง‘๋„๋ก ํ•œ๋‹ค.


Monitor

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

  • ์ฝ”๋”ฉํ•˜๊ธฐ ํž˜๋“ค๋‹ค. - ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ์„ ๋•Œ ๋ฒ„๊ทธ ์žก๊ธฐ ํž˜๋“ฆ
  • ์ •ํ™•์„ฑ(correctness)์˜ ์ž…์ฆ์ด ์–ด๋ ต๋‹ค.
  • ์ž๋ฐœ์  ํ˜‘๋ ฅ(voluntary cooperation)์ด ํ•„์š”ํ•˜๋‹ค.
  • ํ•œ ๋ฒˆ์˜ ์‹ค์ˆ˜๊ฐ€ ๋ชจ๋“  ์‹œ์Šคํ…œ์ด ์น˜๋ช…์ ์ธ ์˜ํ–ฅ์„ ๋ผ์นœ๋‹ค.

์˜ˆ

V(mutex)
critical section
P(mutex)
  • Mutual exclusion์ด ๊นจ์ง
P(mutex)
critical section
P(mutex)
  • Deadlock

  • ์œ„ ๊ฒฝ์šฐ๋“ค์ฒ˜๋Ÿผ ์ˆœ์„œ๊ฐ€ ๋ฐ”๋€Œ๊ฑฐ๋‚˜ ๊ฐ™์€ ์—ฐ์‚ฐ์„ ๋‘ ๋ฒˆ ์“ฐ๋Š” ์‹ค์ˆ˜๊ฐ€ ์ƒ๊ธฐ๋ฉด ์˜ค์ž‘๋™์ด ์ƒ๊ธด๋‹ค.

Monitor

  • ๋™์‹œ ์ˆ˜ํ–‰ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค ์‚ฌ์ด์—์„œ abstract data type์˜ ์•ˆ์ „ํ•œ ๊ณต์œ ๋ฅผ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•œ high-level synchronization construct
  • ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ class์— ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์™€ ํ•จ์ˆ˜๋ฅผ ๋‹ด์•„์„œ ์‚ฌ์šฉํ•˜๋“ฏ์ด ๊ณต์œ  ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‹ˆํ„ฐ ์•ˆ์— ์„ ์–ธํ•˜๊ณ  ๊ณต์œ  ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋ ค๋ฉด ๋ชจ๋‹ˆํ„ฐ ๋‚ด๋ถ€์˜ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ๋งŒ ํ•˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•
  • ๋ชจ๋‹ˆํ„ฐ ๋‚ด์˜ ํ•จ์ˆ˜๋Š” ํ•œ ๋ฒˆ์— ํ•˜๋‚˜๋งŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— lock์„ ๊ฑธ ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ทธ๋ž˜์„œ ํ”„๋กœ๊ทธ๋ž˜๋จธ ์ž…์žฅ์—์„œ๋Š” ์ข€ ๋” ๊ฐ„ํŽธํ•˜๊ฒŒ ํ”„๋กœ๊ทธ๋žจ์„ ์งค ์ˆ˜ ์žˆ๋‹ค.


์ถœ์ฒ˜