Post

[OS] Operating System(7-1): Synchronization Examples

[OS] Operating System(7-1): Synchronization Examples

๐Ÿ€ ์šด์˜์ฒด์ œ ์ „๊ณต ์ˆ˜์—… ์ •๋ฆฌ

Synchronization ๋ฌธ์ œ๋“ค์˜ ์˜ˆ์‹œ์ธ bounded-buffer(์œ ํ•œ ๋ฒ„ํผ), readers-writers(์ฝ๊ธฐ-์“ฐ๊ธฐ), dining philosophers(์‹์‚ฌํ•˜๋Š” ์ฒ ํ•™์ž)๋ฌธ์ œ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž

Bounded-Buffer Problem


๐Ÿ“šBounded-Buffer Problem: ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ  ๋ฒ„ํผ์— ๋„ฃ๊ณ  ๋นผ๋Š” ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋™๊ธฐํ™” ๋ฌธ์ œ(=Producer-Consumer Problem)

  • n๊ฐœ์˜ buffer: ๊ฐ ๋ฒ„ํผ๋Š” ํ•œ ๊ฐœ์˜ ์•„์ดํ…œ ์ €์žฅ ๊ฐ€๋Šฅ
  • Semaphore:
    • mutex: ๊ฐ’ 1๋กœ ์ดˆ๊ธฐํ™”(์ƒํ˜ธ ๋ฐฐ์ œ๋ฅผ ์œ„ํ•œ binary semaphore)
    • full: ๊ฐ’ 0์œผ๋กœ ์ดˆ๊ธฐํ™”(์ฑ„์›Œ์ง„ ๋ฒ„ํผ ์ˆ˜)
    • empty: ๊ฐ’ n์œผ๋กœ ์ดˆ๊ธฐํ™”(๋น„์–ด์žˆ๋Š” ๋ฒ„ํผ ์ˆ˜)

semaphore์˜ ๊ฐ’ = resource ๊ฐœ์ˆ˜

  • counter ๋ณ€์ˆ˜ ์—†์ด mutex๋งŒ ์‚ฌ์šฉํ•ด์„œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ ๋ชปํ•จ!
  • Counting semaphore์ธ full, empty๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํšจ์œจ์ !

  • producer process ๊ตฌ์กฐ:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    while (true) {
      // ์•„์ดํ…œ ์ƒ์‚ฐ
      /* produce an item in next_produced */
        
      wait(empty);    // ๋น„์–ด์žˆ๋Š” ๋ฒ„ํผ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ
      wait(mutex);    // ์ž„๊ณ„ ์˜์—ญ ์ง„์ž…์„ ์œ„ํ•œ ์ž ๊ธˆ ํš๋“
        
      /* add next_produced to the buffer */
        
      signal(mutex);  // ์ž„๊ณ„ ์˜์—ญ ํƒˆ์ถœ ๋ฐ ์ž ๊ธˆ ํ•ด์ œ
      signal(full);   // ์ฑ„์›Œ์ง„ ๋ฒ„ํผ ์ˆ˜ ์ฆ๊ฐ€
    }
    
  • consumer process ๊ตฌ์กฐ:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    while (true) {
      wait(full);     // ์ฑ„์›Œ์ง„ ๋ฒ„ํผ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ
      wait(mutex);    // ์ž„๊ณ„ ์˜์—ญ ์ง„์ž…์„ ์œ„ํ•œ ์ž ๊ธˆ ํš๋“
        
      /* remove an item from buffer to next_consumed */
        
      signal(mutex);  // ์ž„๊ณ„ ์˜์—ญ ํƒˆ์ถœ ๋ฐ ์ž ๊ธˆ ํ•ด์ œ
      signal(empty);  // ๋น„์–ด์žˆ๋Š” ๋ฒ„ํผ ์ˆ˜ ์ฆ๊ฐ€
        
      /* consume the item in next_consumed */
    }
    
  • producer์™€ consumer๊ฐ€ ๋ณ„๋„์˜ mutex๋ฝ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ์œจ์ !
  • โ†’ ์ƒ์‚ฐ์ž์™€ ์†Œ๋น„์ž๊ฐ€ ๋™์‹œ์— ์‹คํ–‰๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ

Readers-Writers Problem


๐Ÿ“šReaders-Writers Problem: ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ณต์œ  ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ๋•Œ, ์ฝ๊ธฐ ์ž‘์—…๊ณผ ์“ฐ๊ธฐ ์ž‘์—… ๊ฐ„์˜ ๋™๊ธฐํ™”๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฌธ์ œ

  • shared data set: ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ณต์œ ํ•˜๋Š” ๋ฐ์ดํ„ฐ
  • Readers: ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ธฐ๋งŒ ํ•˜๊ณ  ์ˆ˜์ •X
  • Writers: ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ์Œ

โœ…problem:

  • ์—ฌ๋Ÿฌ readers๋Š” ๋™์‹œ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์–ด์•ผํ•จ
  • writer๋Š” ๋…์ ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•ด์•ผ ํ•จ(ํ•œ ๋ฒˆ์— ์˜ค์ง ํ•˜๋‚˜์˜ writer)
  • ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ ์œ ์ง€ + ๋™์‹œ์„ฑ ์ตœ๋Œ€ํ™”

๐Ÿ’พShared Data:

  • Data set: ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ ‘๊ทผํ•˜๋Š” ๊ณต์œ  ๋ฐ์ดํ„ฐ
  • Semaphore rw_mutex: ๊ฐ’์ด 1๋กœ ์ดˆ๊ธฐํ™”๋œ ์„ธ๋งˆํฌ์–ด, reader์™€ writer์˜ ์ƒํ˜ธ๋ฐฐํƒ€ ์ ‘๊ทผ์„ ๊ด€๋ฆฌ
  • Semaphore mutex: ๊ฐ’์ด 1๋กœ ์ดˆ๊ธฐํ™”๋œ ์„ธ๋งˆํฌ์–ด, reader๊ฐ€ read_count๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
  • Integer read_count: 0์œผ๋กœ ์ดˆ๊ธฐํ™”๋œ ๋ณ€์ˆ˜, ํ˜„์žฌ ์ง„ํ–‰ ์ค‘์ธ reader์˜ ์ˆ˜

  • Writer Process:
    1
    2
    3
    4
    5
    6
    7
    
    while (true) {
      wait(rw_mutex);    // ๋…์ ์  ์ ‘๊ทผ ๊ถŒํ•œ ํš๋“
        
      /* writing is performed */
        
      signal(rw_mutex);  // ์ ‘๊ทผ ๊ถŒํ•œ ํ•ด์ œ
    }
    
  • ์˜ค์ง ํ•œ ๊ฐœ์˜ writer๋งŒ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ
  • ์ด ํ•ด๋Š” multiple reader๋ฅผ ํ—ˆ์šฉํ•˜์ง€๋งŒ writer๊ฐ€ ์ง€์†์ ์œผ๋กœ ๊ตถ์„ ์ˆ˜ ์žˆ๋‹ค.
  • โ†’ โ€˜reader ์„ ํ˜ธโ€™ ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • Reader Process:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    while (true) {
      wait(mutex);       // read_count ์—…๋ฐ์ดํŠธ ๋ณดํ˜ธ๋ฅผ ์œ„ํ•œ ์ž ๊ธˆ ํš๋“
      read_count++;      // ์ฝ๊ธฐ ํ”„๋กœ์„ธ์Šค ์ˆ˜ ์ฆ๊ฐ€
        
      // ์œ ์ผํ•œ reader๋ผ๋ฉด writer์™€ ๊ฒฝ์Ÿ, ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ๋‹ค๋ฅธ reader๊ฐ€ ๋“ค์–ด์˜ค๋Š” ๊ฒƒ์„ ํ—ˆ์šฉ
      if (read_count == 1) {
          wait(rw_mutex); // ์ฒซ ๋ฒˆ์งธ reader๊ฐ€ writer ์ ‘๊ทผ ์ฐจ๋‹จ
      }
        
      signal(mutex);     // read_count ์—…๋ฐ์ดํŠธ ์™„๋ฃŒ, ์ž ๊ธˆ ํ•ด์ œ
        
      /* reading is performed */ //โ†’ reader๊ฐ€ ์ค‘๋ณตํ•ด์„œ ๋“ค์–ด์˜ค๋Š” ๊ฒƒ์„ ํ—ˆ์šฉ
        
      wait(mutex);       // read_count ์—…๋ฐ์ดํŠธ ๋ณดํ˜ธ๋ฅผ ์œ„ํ•œ ์ž ๊ธˆ ์žฌํš๋“
      read_count--;      // ์ฝ๊ธฐ ํ”„๋กœ์„ธ์Šค ์ˆ˜ ๊ฐ์†Œ
        
      if (read_count == 0) { // ๋” ์ด์ƒ reader๊ฐ€ ์—†์œผ๋ฏ€๋กœ writer ํ—ˆ์šฉ
          signal(rw_mutex); // ๋งˆ์ง€๋ง‰ reader๊ฐ€ writer ์ ‘๊ทผ ํ—ˆ์šฉ
      }
        
      signal(mutex);     // read_count ์—…๋ฐ์ดํŠธ ์™„๋ฃŒ, ์ž ๊ธˆ ํ•ด์ œ
    }
    
  • ์ฒซ ๋ฒˆ์งธ reader๊ฐ€ ๋“ค์–ด์˜ฌ ๋•Œ๋งŒ rw_mutex๋ฅผ ํš๋“ โ†’ writer์˜ ์ ‘๊ทผ์„ ์ฐจ๋‹จ
  • ๋งˆ์ง€๋ง‰ reader๊ฐ€ ๋‚˜๊ฐˆ ๋•Œ๋งŒ rw_mutex๋ฅผ ํ•ด์ œ โ†’ ๋ชจ๋“  reader๊ฐ€ ์ž‘์—…์„ ์™„๋ฃŒํ•˜๋ฉด writer๊ฐ€ ์ ‘๊ทผ ๊ฐ€๋Šฅ

Readers-Writers Problem Variations


์ฝ๊ธฐ-์“ฐ๊ธฐ ๋ฌธ์ œ์—๋Š” ์—ฌ๋Ÿฌ ๋ณ€ํ˜•์ด ์กด์žฌ, ๋ชจ๋‘ ์–ด๋–ค ํ˜•ํƒœ์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ํฌํ•จ

1. First variation - Reader Priority

  • reader๋Š” ๋Œ€๊ธฐํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์‹คํ–‰๋จ
  • writer๋Š” ๋ชจ๋“  reader๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ
    • โ†’ writer์˜ starvation ๊ฐ€๋Šฅ์„ฑ ์žˆ์Œ!

2. second variation - Writer Priority

  • writer๊ฐ€ ๋Œ€๊ธฐ ์ค‘์ด๋ฉด ์ƒˆ๋กœ์šด reader๋Š” ์‹œ์ž‘ํ•  ์ˆ˜ ์—†์Œ
    • reader์˜** ์ค‘๋ณต์€ ์ตœ๋Œ€ํ•œ ํ—ˆ์šฉํ•˜์ง€๋งŒ ๊ธฐ๋‹ค๋ฆฌ๋Š” writer๊ฐ€ ์žˆ์œผ๋ฉด **reader๋Š” writer๋ฅผ ์•ž์ง€๋ฅด์ง€ ๋ชปํ•จ
    • ๋Šฆ๊ฒŒ ์˜จ writer๋Š” ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋Š” reader๋ฅผ ์•ž์ง€๋ฅผ ์ˆ˜ ์žˆ๋‹ค
  • writer๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋นจ๋ฆฌ ์‹คํ–‰๋จ
    • reader์˜ starvation ๊ฐ€๋Šฅ์„ฑ ์žˆ์Œ!

๋‘ ๋ณ€ํ˜• ๋ชจ๋‘ starvation์˜ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋ฉฐ, ์ด๋กœ ์ธํ•ด ๋” ๋งŽ์€ ๋ณ€ํ˜•์ด ์ƒ๊น€

Fair Solution

  • ๊ณต์ •ํ•œ reader-writer: ์„ ์ฐฉ์ˆœ์œผ๋กœ CS์— ๋“ค์–ด๊ฐ€๋ฉด์„œ reader์˜ ์ค‘๋ณต์„ ์ตœ๋Œ€ํ•œ ํ—ˆ์šฉํ•˜๋Š” ๋ฐฉ์‹
    • ๋Šฆ๊ฒŒ ์˜จ reader/writer๊ฐ€ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋Š” ๋‹ค๋ฅธ reader/writer๋ฅผ ์•ž์ง€๋ฅด์ง€ ๋ชปํ•จ!
  • ํ”„๋กœ์„ธ์Šค์˜ ๋„์ฐฉ ์ˆœ์„œ(FIFO)์— ๋”ฐ๋ผ ์ ‘๊ทผ ๊ถŒํ•œ ๋ถ€์—ฌ
  • ๊ฐ€๋Šฅํ•œ ํ•œ ๋งŽ์€ ์ฝ๊ธฐ ํ”„๋กœ์„ธ์Šค ๋™์‹œ ์ ‘๊ทผ ํ—ˆ์šฉ
  • ๋Šฆ๊ฒŒ ๋„์ฐฉํ•œ ํ”„๋กœ์„ธ์Šค๋Š” ๋จผ์ € ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ถ”์›”ํ•  ์ˆ˜ ์—†์Œ

Dining Philosophers Problem


๐Ÿ“šDining Philosophers Problem: ๊ต์ฐฉ ์ƒํƒœ(deadlock)์™€ ๊ธฐ์•„ ์ƒํƒœ(starvation)๋ฅผ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•œ ์œ ๋ช…ํ•œ ์˜ˆ์ œ alt text

  • 5๋ช…์˜ ์ฒ ํ•™์ž๊ฐ€ ์›ํ˜• ํ…Œ์ด๋ธ”์— ์•‰์•„ ์žˆ๋‹ค.
  • ๊ฐ ์ฒ ํ•™์ž ์‚ฌ์ด์—๋Š” ํ•˜๋‚˜์˜ ์ “๊ฐ€๋ฝ(chopstick)์ด ์žˆ์–ด ์ด 5๊ฐœ์˜ ์ “๊ฐ€๋ฝ์ด ์žˆ๋‹ค.
  • ์ฒ ํ•™์ž๋“ค์€ ์ƒ๊ฐํ•˜๊ธฐ(thinking)์™€ ๋จน๊ธฐ(eating)๋ฅผ ๋ฒˆ๊ฐˆ์•„ ์ˆ˜ํ–‰
  • ์ฒ ํ•™์ž๊ฐ€ ์‹์‚ฌ๋ฅผ ํ•˜๋ ค๋ฉด ์ขŒ์šฐ ์–‘์ชฝ์˜ ์ “๊ฐ€๋ฝ 2๊ฐœ๋ฅผ ๋ชจ๋‘ ์ง‘์–ด์•ผ ํ•œ๋‹ค.
  • ์ “๊ฐ€๋ฝ์€ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์”ฉ ์ง‘์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์‹์‚ฌ๊ฐ€ ๋๋‚˜๋ฉด ๋‘ ์ “๊ฐ€๋ฝ์„ ๋ชจ๋‘ ๋‚ด๋ ค๋†“๋Š”๋‹ค.

Shared Data:

  • Bowl of rice: ๊ณต์œ  data set
  • chopstick [5]: ๊ฐ๊ฐ 1๋กœ ์ดˆ๊ธฐํ™”๋œ semaphore ๋ฐฐ์—ด

์„ธ๋งˆํฌ์–ด๋ฅผ ํ™œ์šฉํ•œ ๊ธฐ๋ณธ์ ์ธ solution


alt text

์œ„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ deadlock ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค!

  • ๋ชจ๋“  ์ฒ ํ•™์ž๊ฐ€ ๋™์‹œ์— ์™ผ์ชฝ ์ “๊ฐ€๋ฝ์„ ์žก์Œ
  • ์˜ค๋ฅธ์ชฝ ์ “๊ฐ€๋ฝ์€ ์ด๋ฏธ ๋‹ค๋ฅธ ์ฒ ํ•™์ž๊ฐ€ ์žก๊ณ  ์žˆ์–ด์„œ ๋Œ€๊ธฐ
  • ๋ชจ๋“  ์ฒ ํ•™์ž๊ฐ€ ๋ฌดํ•œ ๋Œ€๊ธฐ ์ƒํƒœ๊ฐ€ ๋จ

โœ…deadlock์„ ํ”ผํ•˜๋Š” ๋ฐฉ๋ฒ•:

  1. ์ “๊ฐ€๋ฝ ๋‘ ๊ฐœ๋ฅผ ๋‹ค ์ง‘์„ ์ˆ˜ ์žˆ์„ ๋•Œ๋งŒ ์ง‘๋Š”๋‹ค.
    • atomic ์—ฐ์‚ฐ์œผ๋กœ ๋‘ ์ “๊ฐ€๋ฝ์„ ๋ชจ๋‘ ์ง‘๊ฑฐ๋‚˜ ์•„์˜ˆ ์ง‘์ง€ ์•Š์Œ
  2. ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ง‘๋Š”๋‹ค.
  3. ์ง์ˆ˜๋ฒˆ ์ฒ ํ•™์ž๋Š” ์™ผ์ชฝโ†’์˜ค๋ฅธ์ชฝ, ํ™€์ˆ˜๋ฒˆ ์ฒ ํ•™์ž๋Š” ์˜ค๋ฅธ์ชฝโ†’์™ผ์ชฝ ์ˆœ์œผ๋กœ ์ง‘๋Š”๋‹ค.
    • circular wait ์กฐ๊ฑด์„ ๊นจ๋œจ๋ฆผ
  4. ํ…Œ์ด๋ธ”์— ์ตœ๋Œ€ 4๋ช…๋งŒ ์•‰๋Š”๋‹ค.
    • ์ตœ๋Œ€ 4๋ช…๋งŒ ํ…Œ์ด๋ธ”์— ๋™์‹œ์— ์•‰์„ ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ โ†’ ์ตœ์†Œ ํ•œ ๋ช…์€ ๋ฌด์กฐ๊ฑด ์ “๊ฐ€๋ฝ ๋‘ ๊ฐœ ๊ฐ€๋Šฅ

Monitor๋ฅผ ์ด์šฉํ•œ solution


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
monitor DiningPhilosophers {
    enum { THINKING, HUNGRY, EATING } state[5];
    condition self[5];
    
    void pickup(int i) {
        state[i] = HUNGRY;
        test(i);
        if (state[i] != EATING) self[i].wait;
    }
    
    void putdown(int i) {
        state[i] = THINKING;
        // test left and right neighbors
        test((i + 4) % 5);
        test((i + 1) % 5);
    }
    
    void test(int i) {
        if ((state[(i + 4) % 5] != EATING) && 
            (state[i] == HUNGRY) && 
            (state[(i + 1) % 5] != EATING)) {
            state[i] = EATING;
            self[i].signal();
        }
    }
    
    // ์ดˆ๊ธฐํ™” ์ฝ”๋“œ
    initialization_code() {
        for (int i = 0; i < 5; i++)
            state[i] = THINKING; // ๋ชจ๋“  ์ฒ ํ•™์ž์˜ ์ดˆ๊ธฐ ์ƒํƒœ๋Š” ์ƒ๊ฐํ•˜๊ธฐ
    }
}
  1. ์ฒ ํ•™์ž์˜ ์ƒํƒœ ๊ด€๋ฆฌ:
    1
    
    enum { THINKING, HUNGRY, EATING } state[5];
    
  • THINKING: ์ฒ ํ•™์ž๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ์ƒํƒœ
  • HUNGRY: ์ฒ ํ•™์ž๊ฐ€ ๋ฐฐ๊ณ ํŒŒ์„œ ์ “๊ฐ€๋ฝ์„ ์ง‘์œผ๋ ค๋Š” ์ƒํƒœ
  • EATING: ์ฒ ํ•™์ž๊ฐ€ ์‹์‚ฌ ์ค‘์ธ ์ƒํƒœ
  1. ์กฐ๊ฑด ๋ณ€์ˆ˜:
    1
    
    condition self[5];
    
  • ๋ฐฐ๊ณ ํ”„์ง€๋งŒ ์ “๊ฐ€๋ฝ์„ ์ง‘์„ ์ˆ˜ ์—†์„ ๋•Œ ๊ธฐ๋‹ค๋ฆฌ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ์กฐ๊ฑด ๋ณ€์ˆ˜
  1. ํ”ฝ์—… ํ•จ์ˆ˜:
    1
    2
    3
    4
    5
    
    void pickup(int i) {
     state[i] = HUNGRY;     // ์ƒํƒœ๋ฅผ ๋ฐฐ๊ณ ํ””์œผ๋กœ ๋ณ€๊ฒฝ
     test(i);               // ์ “๊ฐ€๋ฝ์„ ์ง‘์„ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธ
     if (state[i] != EATING) self[i].wait;  // ์‹์‚ฌํ•  ์ˆ˜ ์—†์œผ๋ฉด ๋Œ€๊ธฐ
    }
    
  2. ๋‚ด๋ ค๋†“๊ธฐ ํ•จ์ˆ˜:
    1
    2
    3
    4
    5
    6
    
    void putdown(int i) {
     state[i] = THINKING;   // ์ƒํƒœ๋ฅผ ์ƒ๊ฐํ•˜๊ธฐ๋กœ ๋ณ€๊ฒฝ
     // ์ขŒ์šฐ ์ด์›ƒ ํ™•์ธ
     test((i + 4) % 5);     // ์™ผ์ชฝ ์ด์›ƒ ํ™•์ธ
     test((i + 1) % 5);     // ์˜ค๋ฅธ์ชฝ ์ด์›ƒ ํ™•์ธ
    }
    
  • test ~: ์ขŒ์šฐ์— ๋ˆ„๊ฐ€ ๋จน๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์œผ๋ฉด ๊นจ์›Œ์คŒ
  1. test ํ•จ์ˆ˜:
    1
    2
    3
    4
    5
    6
    7
    8
    
    void test(int i) {
     if ((state[(i + 4) % 5] != EATING) &&   // ์™ผ์ชฝ ์ด์›ƒ์ด ์‹์‚ฌ ์ค‘์ด ์•„๋‹ˆ๊ณ 
         (state[i] == HUNGRY) &&             // ์ž์‹ ์ด ๋ฐฐ๊ณ ํ”„๊ณ 
         (state[(i + 1) % 5] != EATING)) {   // ์˜ค๋ฅธ์ชฝ ์ด์›ƒ์ด ์‹์‚ฌ ์ค‘์ด ์•„๋‹ˆ๋ฉด
         state[i] = EATING;                  // ์ƒํƒœ๋ฅผ ์‹์‚ฌ ์ค‘์œผ๋กœ ๋ณ€๊ฒฝ
         self[i].signal();                   // ๋Œ€๊ธฐ ์ค‘์ด๋˜ ์ฒ ํ•™์ž ๊นจ์šฐ๊ธฐ
     }
    }
    

์ฒ ํ•™์ž ํ”„๋กœ์„ธ์Šค๋Š” ๋ชจ๋‹ˆํ„ฐ์˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์‹คํ–‰๋จ:

1
2
3
4
5
DiningPhilosophers.pickup(i);  // ์ “๊ฐ€๋ฝ ์ง‘๊ธฐ ์‹œ๋„

/** EAT **/  // ์‹์‚ฌ

DiningPhilosophers.putdown(i);  // ์ “๊ฐ€๋ฝ ๋‚ด๋ ค๋†“๊ธฐ
  • No deadlock, but starvation is possible
    • ํŠน์ • ์ฒ ํ•™์ž๊ฐ€ ๊ณ„์†ํ•ด์„œ ์‹์‚ฌ ๊ธฐํšŒ๋ฅผ ์–ป์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ๋‹ค

๊ฐ problem ์ •๋ฆฌ


  • bounded-buffer: ์„ธ๋งˆํฌ์–ด ์‚ฌ์šฉ(mutex, empty, full). ์นด์šดํŒ… ์„ธ๋งˆํฌ์–ด๋กœ ๋ฒ„ํผ ์ƒํƒœ ์ถ”์ . ์ƒ์‚ฐ์ž์™€ ์†Œ๋น„์ž ๊ฐ„ ๋™๊ธฐํ™”

  • reader-writer: ์„ธ๋งˆํฌ์–ด์™€ ์นด์šดํ„ฐ(mutex, rw_mutex, read_count) ์‚ฌ์šฉ. ์ฝ๊ธฐ ํ”„๋กœ์„ธ์Šค ๋™์‹œ ์ ‘๊ทผ ํ—ˆ์šฉ, ์“ฐ๊ธฐ ํ”„๋กœ์„ธ์Šค ๋…์  ์ ‘๊ทผ ๋ณด์žฅ

  • dining philosophers: ์„ธ๋งˆํฌ์–ด(chopstick[5]) ๋˜๋Š” ๋ชจ๋‹ˆํ„ฐ ์‚ฌ์šฉ. ๋ชจ๋‹ˆํ„ฐ๋Š” ์กฐ๊ฑด ๋ณ€์ˆ˜์™€ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ํ†ตํ•ด ๊ต์ฐฉ ์ƒํƒœ ๋ฐฉ์ง€

This post is licensed under CC BY 4.0 by the author.