๐Ÿธ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)

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

  • ํ™ˆ

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

์ธ๊ธฐ ๊ธ€

ํƒœ๊ทธ

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

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

์ตœ๊ทผ ๊ธ€

ํ‹ฐ์Šคํ† ๋ฆฌ

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

Minzzi์•ผ

CS/Operating System

[์šด์˜์ฒด์ œ] Chapter7. Synchronization Examples

2022. 6. 1. 20:55

1. Classic Problems of Synchronization

  • The bounded-buffer problem
  • The readers-writers problem
  • The dining-philosophers problem

 

1) The Bounded-Buffer Problem

๋‘ ์ข…๋ฅ˜์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ๋‹ค. ํ•˜๋‚˜๋Š” Producer, ๋˜ ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” Consumer์ด๋‹ค. ์ด๋Š” ์ƒ์‚ฐ์ž-์†Œ๋น„์ž ๋ฌธ์ œ(Producer-Consumer Problem)์ด๋ผ๊ณ ๋„ ๋ถˆ๋ฆฐ๋‹ค. ์—ฌ๊ธฐ์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ ์€ ์–ด๋А producer๊ฐ€ ๋ฒ„ํผ ์ค‘ ๋นˆ ๊ณณ์— ๋ฐ์ดํ„ฐ๋ฅผ ์“ฐ๋ ค๊ณ  ํ•  ๋•Œ, interrupt๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šคํ•œํ…Œ ๊ณต์œ ์ž์›์ด ๋„˜์–ด๊ฐ€์„œ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ•ด๋‹นํ•˜๋Š” ๋นˆ ๊ณณ์— ๋ฐ์ดํ„ฐ๋ฅผ ์“ธ ๋•Œ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด ๋‘˜ ์ค‘ ํ•œ ํ”„๋กœ์„ธ์Šค์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ์‹ค๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. 

  • ๋งŒ์•ฝ buffer๊ฐ€ ๊ฝ‰ ์ฐผ๋‹ค๋ฉด producer๋Š” consumer๊ฐ€ item์„ ์‚ญ์ œํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค. 
    • producer๋Š” buffer ์•ˆ์— empty space๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
    • # of empty slot ์€ semaphore empty์— ์˜ํ•ด ๋‚˜ํƒ€๋‚˜์ง„๋‹ค. 
  • ๋งŒ์•ฝ buffer๊ฐ€ ๋น„์—ˆ๋‹ค๋ฉด consumer๋Š” producer๊ฐ€ item์„ ๋„ฃ์„ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค. 
    • consumer๋Š” buffer ์•ˆ์— item์ด ํ•„์š”ํ•˜๋‹ค. 
    • # of item์€ semaphore full์— ์˜ํ•ด์„œ ๋‚˜ํƒ€๋‚˜์ง„๋‹ค. 
  • Producer-consumer problem with bounded buffer
    • Semaphores: full = 0, empty = n, mutex = 1;
    • ๋ฒ„ํผ์˜ ๊ฐœ์ˆ˜ n, binary semaphore : mutex, counting semaphore: empty, full
//Producer
while(true){
    ...
    /* produce an item in next_produced(์ƒˆ๋กœ์šด item ํ•˜๋‚˜ ์ƒ์„ฑ) */
    ...
    wait(empty) // empty ๋Š” empty-1์ด ๋œ๋‹ค. empty๊ฐ€ 1~n ๊ฐ’์ค‘์—์„œ ์‹œ์ž‘ํ–ˆ๋‹ค๋ฉด ๋‹ค์Œ์ค„๋กœ ๋„˜์–ด๊ฐ.
    //๋งŒ์•ฝ empty๊ฐ€ 0์ด์—ˆ๋‹ค๋ฉด -1์ด ๋˜์–ด block๋Œ
    wait(mutex) 
    ...
    /* add next produced to the buffer(๋ฒ„ํผ์— ์ƒˆ๋กœ ์ƒ์„ฑ๋œ item์„ ์ถ”๊ฐ€) */
    ...
    signal(mutex); //๋ฒ„ํผ์— item์„ ์ถ”๊ฐ€ํ–ˆ์œผ๋ฉด, 
    //binary semaphore์˜ signal ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ critical section์˜ ํƒˆ์ถœ์„ ์•Œ๋ฆฐ๋‹ค.
    signal(full); //signal(full)์„ ํ˜ธ์ถœํ•ด์„œ 0์˜ ์ดˆ๊ธฐ๊ฐ’์„ count++๋ฅผ ํ†ตํ•ด 1๋กœ ๋งŒ๋“ค์–ด์ค€๋‹ค.
}
//Consumer
while(true){
    wait(full); // ๋ฐ์ดํ„ฐ๋ฅผ ๊บผ๋‚ด๊ธฐ ์œ„ํ•ด full ์ž์›์„ ์–ป๋Š”๋‹ค. 
    //๋ฒ„ํผ์— item์ด ํ•œ ๋ฒˆ๋„ ์•ˆ๋“ค์–ด๊ฐ”๋‹ค๋ฉด 0์€ -1์ด ๋˜์–ด block์— ๊ฑธ๋ฆฐ๋‹ค.
    wait(mutex); //full ์ž์›์ด ์žˆ๋‹ค๋ฉด lock์„ ๊ฑธ๊ธฐ ์œ„ํ•ด mutex๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. 
    ...
    /* remove an item from buffer to next_consumed(ํ•ด๋‹น ๋ฒ„ํผ์—์„œ item์„ ๊บผ๋ƒ„) */
    ...
    signal(mutex); //item์„ ๋นผ์˜จ ์ดํ›„ signal ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ critical section ํƒˆ์ถœ์„ ์•Œ๋ฆฐ๋‹ค. 
    signal(empty); //signal(empty)๋ฅผ ํ˜ธ์ถœํ•ด ๋ฐ์ดํ„ฐ๊ฐ€ ์ฑ„์›Œ์ ธ ์žˆ๋Š” ๋ฒ„ํผ์˜ ๊ณต๊ฐ„ ๊ฐœ์ˆ˜ ํ•˜๋‚˜๋ฅผ ๋บ€๋‹ค.
    ...
    /* consume the item in next consumed(item์„ ์†Œ๋น„ํ•จ) */
    ...
}

 

2) The Readers-Writers Problem

Readers์™€ Writers๋Š” ํ•˜๋‚˜์˜ ๊ณต์œ ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. Readers๋Š” ๋™์‹œ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ํ•œ writer๊ฐ€ shared data์— ์ ‘๊ทผํ•  ๋•Œ, ์–ด๋–ค thread๋„ ๊ทธ๊ฒƒ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค. 

 

  • Behavior of a writer
    • ๋งŒ์•ฝ ํ•œ thread๊ฐ€ critical section์— ์žˆ์„๋•Œ, ๋ชจ๋“  writers์€ ๋ฌด์กฐ๊ฑด ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค. 
    • writer์€ ์˜ค์ง ์–ด๋–ค thread๋„ critical section์— ์žˆ์ง€ ์•Š์„ ๋•Œ์—๋งŒ ์ง„์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค. 
      • ๋ชจ๋“  thread๋“ค์ด critical section์— ์ง„์ž…ํ•˜๋Š” ๊ฒƒ์œผ๋กœ๋ถ€ํ„ฐ ์ด๋ฅผ ์˜ˆ๋ฐฉํ•ด์•ผ ํ•œ๋‹ค.
  • Behavior of a reader
    • ๋งŒ์•ฝ ์–ด๋–ค writer๋„ critical section์— ์žˆ์ง€ ์•Š์œผ๋ฉด, ๊ทธ reader๋Š” critical section์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. 
    • ๋งŒ์•ฝ ์–ด๋–ค writer๊ฐ€ critical section์— ์žˆ๋‹ค๋ฉด, reader๋Š” ๊ทธ writer๊ฐ€ critical section์— ๋น ์ ธ ๋‚˜์˜ฌ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค. 
    • reader๊ฐ€ critical section์— ์žˆ์„ ๋•Œ, ์•„๋ฌด reader๋‚˜ critical section์— ์ง„์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ writer์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. 
      • ์ฒซ๋ฒˆ์งธ reader์˜ condition์€ ๋’ค๋”ฐ๋ผ์˜ค๋Š” reader๋“ค๊ณผ ๋‹ค๋ฅด๋‹ค.
//Shared data
semaphore mutex = 1;
semaphore rw_mutex = 1;
int read_count = 0;
//Writer
while(true){
	//writer์€ ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•˜๋ฉด ๋‹ค๋ฅธ ๋ชจ๋“  ํ”„๋กœ์„ธ์Šค๋“ค์˜ ์ ‘๊ทผ์„ ์ฐจ๋‹จํ•จ.
    //binary semaphore๋กœ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋“ค์˜ critical section ์ง„์ž…์„ ์ผ์ฒด ์ฐจ๋‹จํ•จ.
    wait(rw_mutex);
    ...
    /* writing is performed(writing ์ˆ˜ํ–‰) */
    ...
    signal(rw_mutex);
}
//Reader
while(true){
	//Reader์—์„œ๋Š” Writer์˜ ์ ‘๊ทผ๋งŒ ๋ง‰์„ ๋ฟœ, Reader๊ฐ€ ๋ช‡ ๋ช…์ด ์ ‘๊ทผํ•˜๋Š”์ง€๋Š” ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š์Œ.
	
    wait(mutex); // read_count์— ๋Œ€ํ•œ mutual exclusion์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•œ ์„ค์ •
    read_count++; // read_count๊ฐ€ 0์ด๋ผ๋ฉด 1๋กœ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค. 
    if(read_count == 1)// read_count๊ฐ€ 1์ด๋ผ๋ฉด wait(rw_mutex)๋ฅผ ์‹คํ–‰, ์ด๋ฅผ ํ†ตํ•ด writer์€ ์ž„๊ณ„๊ตฌ์—ญ์— ์ง„์ž… ๋ชปํ•จ.
    	wait(rw_mutex);//reader๋Š” read_count๋ฅผ ์ฆ๊ฐ€์‹œํ‚ฌ ๋ฟ, wait(rw_mutex)๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ž„๊ณ„๊ตฌ์—ญ์— ๊ทธ๋ƒฅ ์ง„์ž….
    signal(mutex);
    ...
    /* reading is performed */
    ...
    wait(mutex);
    read_count--;
    if(read_count == 0)//์ž„๊ณ„๊ตฌ์—ญ์— ๋จธ๋ฌผ๋Ÿฌ ์žˆ๋Š” Reader๊ฐ€ ํ•˜๋‚˜๋„ ์—†์„ ๊ฒฝ์šฐ signal(rw_mutex)๋ฅผ ํ˜ธ์ถœ
    	signal(rw_mutex);//๊ทธ๋Ÿผ์œผ๋กœ์จ writer๊ฐ€ ๊ณต์œ  ์ž์›์— ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋‹ค.
    signal(mutex);
}

 

3) The dining-philosophers problem(์‹์‚ฌํ•˜๋Š” ์ฒ ํ•™์ž ๋ฌธ์ œ)

'์‹์‚ฌํ•˜๋Š” ์ฒ ํ•™์ž ๋ฌธ์ œ'๋Š” 5๋ช…์˜ ์ฒ ํ•™์ž๊ฐ€ ์‹์‚ฌ๋ฅผ ํ•˜๊ณ  ์žˆ๋Š” ์ƒํ™ฉ์„ ๊ฐ€์ •ํ•œ ๋ฌธ์ œ์ด๋‹ค. 5๋ช…์˜ ์ฒ ํ•™์ž๋“ค์ด ์›ํ˜•์˜ ํ…Œ์ด๋ธ”์— ์•‰์•„ ์žˆ๋Š”๋ฐ ์ฒ ํ•™์ž๋“ค ์‚ฌ์ด์—๋Š” ์ “๊ฐ€๋ฝ ํ•œ ์ง๋งŒ ๋†“์—ฌ์žˆ๊ณ  ์ฒ ํ•™์ž ์•ž์—๋Š” ์Œ์‹์ด ๋†“์—ฌ์žˆ๋‹ค. ์ฒ ํ•™์ž๋Š” ๋ฐฐ๊ฐ€๊ณ ํ”„๋ฉด ์–‘ ์˜†์— ์žˆ๋Š” ์ “๊ฐ€๋ฝ์„ ์‚ฌ์šฉํ•ด์„œ ์‹์‚ฌ๋ฅผ ํ•˜๊ณ  ๋‹ค์‹œ ์ “๊ฐ€๋ฝ์„ ์›์œ„์น˜์— ๋‘๊ณ  ์ƒ๊ฐ์„ ํ•ด์•ผํ•œ๋‹ค. ์ด๋•Œ ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ๋Š” ํ•œ๋ช…์ด ์Œ์‹์„ ๋จน๊ณ  ์žˆ๋‹ค๋ฉด ์–‘ ์˜†์— ์•‰์€ ์ฒ ํ•™์ž ๋‘๋ช…์€ ๋ฐฐ๊ฐ€ ๊ณ ํŒŒ๋„ ์Œ์‹์„ ๋จน์„ ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ด ์˜จ๋‹ค. ๋”ฐ๋ผ์„œ ์ “๊ฐ€๋ฝ์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๋ฌธ์ œ ํ•ด๊ฒฐ์ด ํ•„์š”ํ•˜๋‹ค. 

 

 

ํ•ด๊ฒฐ์ฑ…์€ deadlock-free์™€ starcation-free๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค. ์ฆ‰, ๊ต์ฐฉ๊ณผ ๊ธฐ์•„๊ฐ€ ์ƒ๊ธฐ์ง€ ์•Š๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ƒ๊ฐํ•ด์•ผ ํ•œ๋‹ค. 

  • Semaphore ํ•ด๊ฒฐ๋ฐฉ๋ฒ•
    • Shared data: Bowl of rice(dataset) / Semaphore chopstick[5] initialized to 1
    • ์•„๋ž˜ ์ฝ”๋“œ๋Š” ํ•ด๊ฒฐ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. ํ•˜์ง€๋งŒ deadlock์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. 
while(true){
    wait(chopstick[i]);			//pick up left chopstick
    wait(chopstick[(i+1) % 5]);		//pick up right chopstick

    /* eat for a while */

    signal(chopstick[i]);		//release left chopstick
    signal(chopstick[(i+1) % 5]);	//release right chopstick

    /* think for a while */
}

Deadlock์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์–ด๋–ค ๊ฒฝ์šฐ์ผ๊นŒ?

- 5๋ช…์˜ ์ฒ ํ•™์ž๊ฐ€ ๋‹ค๊ฐ™์ด ๋ฐฐ๊ณ ํŒŒ์„œ ๋‹ค๊ฐ™์ด ๋™์‹œ์— ์ž์‹  ์™ผ์ชฝ์˜ ์ “๊ฐ€๋ฝ์„ ์žก๋Š”๋‹ค๋ฉด chopstick์˜ ๋ชจ๋“  ์›์†Œ๋Š” 0์ด ๋œ๋‹ค. ๊ฒฐ๊ตญ ์ฒ ํ•™์ž๋Š” ์˜ค๋ฅธ์ชฝ ์ “๊ฐ€๋ฝ์„ ์˜์›ํžˆ ์žก์„ ์ˆ˜ ์—†๋‹ค. -> ์ด๋ ‡๊ฒŒ Deadlock์ด ๋ฐœ์ƒ

Starvation์˜ ๊ฒฝ์šฐ๋Š”?

- ๊ฐ€์šด๋ฐ ์‚ฌ๋žŒ์ด ๊ปด์„œ ์–‘์ชฝ์˜ ์‚ฌ๋žŒ๋งŒ ๋ฐฅ์„ ๋จน๊ณ  ๊ฐ€์šด๋ฐ ์‚ฌ๋žŒ์€ ๋ฐฅ์„ ๋จน์ง€ ๋ชปํ•˜๋Š” starvation์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

 

  • Deadlock์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•(์•„๋ž˜ 3๊ฐ€์ง€ ์กฐ๊ฑด ์ค‘ ํ•˜๋‚˜๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์€ starvation์˜ ๊ฐ€๋Šฅ์„ฑ์„ ์—…์• ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.)
    • ์ตœ๋Œ€ 4๋ช…์˜ ์ฒ ํ•™์ž๋งŒ์ด ํ…Œ์ด๋ธ”์— ๋™์‹œ์— ์•‰์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.
    • ํ•œ ์ฒ ํ•™์ž๊ฐ€ ๋‘ ๊ฐœ๋ฅผ ๋ชจ๋‘ ์ง‘์„ ์ˆ˜ ์žˆ์„ ๋•Œ๋งŒ ์ “๊ฐ€๋ฝ์„ ์ง‘๋„๋ก ํ•œ๋‹ค.
    • ๋น„๋Œ€์นญ ํ•ด๊ฒฐ์•ˆ์„ ์‚ฌ์šฉํ•œ๋‹ค. ex)ํ™€์ˆ˜๋ฒˆ์งธ ์ฒ ํ•™์ž๋Š” ์™ผ์ชฝ ์ “๊ฐ€๋ฝ๋ถ€ํ„ฐ ์ง‘์–ด์•ผ ํ•˜๊ณ  ์ง์ˆ˜๋ฒˆ์งธ ์ฒ ํ•™์ž๋Š” ์˜ค๋ฅธ์ชฝ ์ “๊ฐ€๋ฝ๋ถ€ํ„ฐ ์ง‘์–ด์•ผ ํ•œ๋‹ค. 
  •  Monitor solution
monitor DiningPhilosophers{
    enum {THINKING; HUNGRY; EATING} state[5];
    condition self[5]; // shared data์˜ ์˜์—ญ์—์„œ ํ”„๋กœ์„ธ์Šค์˜ ๋Œ€๊ธฐ์ƒํƒœ๋ฅผ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•œ ๋ณ€์ˆ˜

    void pickup(int i){
        state[i] = HUNGRY; // ์ “๊ฐ€๋ฝ์„ ๋“ค๋ฉด ํ•ด๋‹น ์ฒ ํ•™์ž์˜ ์ƒํƒœ๋Š” ๋ฐฐ๊ณ ํ”ˆ ์ƒํƒœ๋กœ ์„ค์ •
        test(i);
        if(state[i] != EATING)
            self[i].wait; // ๋‹ค๋ฅธ ์ฒ ํ•™์ž๊ฐ€ eatingํ•˜๊ณ  ์žˆ์–ด์„œ ํ•ด๋‹น state์˜ ์ƒํƒœ๋ฅผ wait๋กœ ์„ค์ •
    }

    void putdown(int i){
        state[i] = THINKING; // ํ•ด๋‹น ์ฒ ํ•™์ž๋Š” ๋‹ค์‹œ ์ƒํƒœ๋ฅผ ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์„ค์ •
        //test left and right neightbors
        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(); // ํ•ด๋‹น ์ฝ”๋“œ๋Š” putdown์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
        }
    }

    void initialization_code(){
        for(int i = 0; i<5; i++)
            state[i] = THINKING;
    }
}

monitor๋ฅผ ์ด์šฉํ•œ dining philosophers problem

- ๊ฐ๊ฐ์˜ ์ฒ ํ•™์ž i๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด pickup()๊ณผ putdown() operation์„ ์‹คํ–‰ํ•œ๋‹ค. 

DiningPhilosopher.pickup(i)
...
/** EAT **/
...
DiningPhilosopher.putdown(i);

์ด ํ•ด๊ฒฐ๋ฒ•์€ Deadlock์€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์ง€๋งŒ starvation์€ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๋‹ค. 

 

2. Synchronization within the Kernel

์ด ๋ถ€๋ถ„์—์„œ๋Š” linux์— ์˜ํ•ด ์ œ๊ณต๋˜๋Š” ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ๋Œ€ํ•ด์„œ ์„ค๋ช…ํ•œ๋‹ค. 

  • Synchronization in Linux
  • Linux : 2.6 ๋ฒ„์ „ ์ด์ „์—๋Š” ๋น„์„ ์ ํ˜• ์ปค๋„์ด์—ˆ๋‹ค. ์ด๋Š” kernel mode์—์„œ ์ž‘๋™ํ•˜๋Š” ํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์„ ์ ๋  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ง€๊ธˆ์€ linux kernel์€ ์™„์ „ํžˆ ์„ ์ ํ˜•์ด๋‹ค. 
  • Linux๋Š” Semaphores(kernel์—์„œ locking์„ ์œ„ํ•ด), atomic integers(์ˆ˜ํ•™์—ฐ์‚ฐ์„ ์œ„ํ•œ), spinlocks(kernel์—์„œ locking์„ ์œ„ํ•ด), ๊ทธ๋ฆฌ๊ณ  reader-writer version of both์„ ์ œ๊ณตํ•œ๋‹ค. 
  • Atomic variables
    •  ์ปดํ“จํ„ฐ ์•„ํ‚คํ…์ณ๊ฐ€ ๊ฐ„๋‹จํ•œ ์ˆ˜ํ•™ ์—ฐ์‚ฐ์„ ์œ„ํ•ด atomin versions์— ๋Œ€ํ•ด ๋ช…๋ น์–ด๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์—, Linux kernel ๋‚ด์—์„œ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋™๊ธฐํ™” ๊ธฐ๋ฒ•
    • atomic_t๋Š” atomic integer์˜ ํƒ€์ž…์ด๋‹ค. 
    • ๋ชจ๋“  math operation์€ interruption์—†์ด ์ˆ˜ํ–‰๋œ๋‹ค. 
    • ex) atomic_t counter; int value; // ์•„๋ž˜์˜ ์ฝ”๋“œ๋Š” atomic integer counter๋ฅผ ์„ ์–ธํ•˜๊ณ  ๋‹ค์–‘ํ•œ atomic์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์ค€๋‹ค. 

  • Mutex locks
    • kernel ๋‚ด์˜ critical section์„ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด์„œ mutex lock์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด linux์—์„œ ๊ฐ€๋Šฅํ•˜๋‹ค.  
    • int mutex_init(struct mutex *lock); // initialize the mutex
    • int mutex_lock(struct mutex *lock); // acquire the mutex, critical section์— ๋“ค์–ด๊ฐ€๊ธฐ ์ „์— ๊ผญ ํ˜ธ์ถœํ•ด์•ผ๋งŒ ํ•œ๋‹ค. ๋งŒ์•ฝ mutex lock์ด ์ด์šฉ๊ฐ€๋Šฅํ•˜์ง€ ์•Š๋‹ค๋ฉด mutex_lock()์„ ํ˜ธ์ถœํ•œ task๋Š” sleep state์— ๋“ค์–ด๊ฐ€๊ณ , lock์˜ ์ฃผ์ธ์ด mutex_unlock()์„ ๋ถ€๋ฅผ ๋•Œ ๊นจ์–ด๋‚œ๋‹ค. 
    • int mutex_unlock(struct mutex *lock); // Release the mutex, must be invoked after exiting the critical section, If the mutex lock is unavailable, a task calling mutex_lock() is put into sleep state and is awakened when the lock's owner invokes mutex_unlock() 
  • Spinlocks(spinlock์€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ lock์„ ์†Œ์œ ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ๊ทธ lock์ด ๋ฐ˜ํ™˜๋  ๋•Œ๊นŒ์ง€ ๊ณ„์† ํ™•์ธํ•˜๋ฉฐ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์ด๋‹ค)
    • spin_lock(), spin_unlock(), etc.
    • SMP machines์—์„œ, ๊ธฐ๋ณธ locking mechanism์€ spinlock์ด๊ณ , ๊ทธ kernel์€ spinlock์ด ์งง์€ ์‹œ๊ฐ„๋™์•ˆ๋งŒ ๋ณด์œ ๋˜๋„๋ก ์„ค๊ณ„๋œ๋‹ค.  
    • ์˜ค์ง ๋‹จ์ผ ํ”„๋กœ์„ธ์‹ฑ ์ฝ”์–ด๋ฅผ ๊ฐ€์ง„ ์ž„๋ฒ ๋””๋“œ ์‹œ์Šคํ…œ ๊ฐ™์€ ๋‹จ์ผ ํ”„๋กœ์„ธ์„œ ๋จธ์‹ ์—์„  spinlock์„ ์‚ฌ์šฉํ•˜๊ธฐ์—” ๋ถ€์ ์ ˆํ•˜๊ณ , kernel ์„ ์ ์„ ํ™œ์„ฑํ™”/ ๋น„ํ™œ์„ฑํ™” ํ•˜์—ฌ ๋Œ€์ฒด๋œ๋‹ค. 
  • Enabling/disabling kernel preemption
    • Linux๋Š” kernel ์„ ์ ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ , ํ™œ์„ฑํ™” ํ•˜๋Š”๋ฐ ํฅ๋ฏธ๋กœ์šด ์ ‘๊ทผ๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค. ๊ทธ๊ฒƒ์€ ์ปค๋„ ์„ ์ ์„ ๋น„ํ™œ์„ฑํ™” ํ•˜๊ณ  ํ™œ์„ฑํ™” ํ•˜๋Š”๋ฐ ๊ฐ„๋‹จํ•œ system calls์„ ์‚ฌ์šฉํ•œ๋‹ค. 
    • preempt_disable(), preempt_enable()
Single Processor Multiple Processors
Disable kernel preemption Acquire spin lock
Enable kernel preemption Release spin lock

3. POSIX Synchronization

POSIX API๋Š” 1) Mutex locks 2) Semaphores 3) Condition variable์„ ์ œ๊ณตํ•œ๋‹ค. 

UNIX, Linux, macOS์—์„œ ๋„๋ฆฌ ์‚ฌ์šฉ๋œ๋‹ค. 

 

1) POSIX Mutex Locks

  • Creating and initializing the lock
#include <pthread.h>
pthread_mutex_t mutex; // global declaration

//create and initialize the mutex lock
pthread_mutex_init(&mutex, NULL); //call before first lock
or
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  • Acquiring and releasing the lock
pthread_mutex_lock(&mutex); // acquire the mutex lock

/* critical section */

pthread_mutex_unlock(&mutex); // release the mutex lock

2) POSIX Semaphores

  • Named semaphores
  • Multiple unrelated processes๋Š” common semaphore๋ฅผ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 
  • Creating and initializing the lock
#include <semaphore.h>
sem_t *sem; // global declaration

//create the semaphore and initialize it to 1
sem = sem_open("SEM", O_CREAT, 0666, 1);
  • Acquiring and releasing the lock
sem_wait(sem); // acquire the semaphore

/* critical section */

sem_post(sem); // release the semaphore
  • Unnamed semaphores
  • Creating and initializing the lock
#include <semaphore.h>
sem_t sem; // global declaration

//Create the semaphore and initialize it to 1
sem_init(&sem, 0, 1);
  • Acquiring and releasing the lock
sem_wait(&sem); // acquire the semaphore

/* critical section */

sem_post(&sem); // release the semaphore

3) POSIX Condition Variables

POSIX๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ C/C++์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์ด๋Ÿฌํ•œ ์–ธ์–ด๋Š” ๋ชจ๋‹ˆํ„ฐ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค. 

POSIX condition variables์€ POSIX mutex lock๊ณผ ์—ฐ๊ด€๋˜์–ด mutual exclution์„ ๋ณด์žฅํ•œ๋‹ค. 

  • Creating and initializing
pthread_mutex_t mutex;
pthread_cond_t cond_var;

pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond_var, NULL);
  • Example
  • ์กฐ๊ฑด a==b๊ฐ€ true๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์Šค๋ ˆ๋“œ
pthread_mutex_lock(&mutex);
while(a!=b)
	pthread_cond_wait(&cond_var, &mutex);
pthread_mutex_unlock(&mutex);
  • condition variable์— ๋Œ€๊ธฐ์ค‘์ธ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—๊ฒŒ ์‹œ๊ทธ๋„์„ ๋ณด๋‚ด๋Š” ์Šค๋ ˆ๋“œ
pthread_mutex_lock(&mutex);
a = b;
pthread_cond_signal(&cond_var);
pthread_mutex_unlock(&mutex);

 

4. Synchronization in Java

Java๋Š” ๊ฐ€์žฅ ๋งŽ์€ synchronization feature์„ ์ œ๊ณตํ•œ๋‹ค.

  • Java monitors
  • Reentrant locks
  • Semaphores
  • Condition variables

1) Java Monitors

Java์˜ ๋ชจ๋“  ๊ฐ์ฒด๋Š” lock์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. 

 

๋จผ์ € ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณด์ž

public class BoundedBuffer<E>
{
    private static final in BUFFER_SIZE = 5;
    private int count, in, out;
    private E[] buffer;

    public BoundedBuffer(){
        count = 0;
        in = 0;
        out = 0;
        buffer = (E[]) new Object[BUFFER_SIZE];
    }

    //Producers call this method
    public synchronized void insert(E item){
    	while(count == BUFFER_SIZE){
        	try{
            	wait();
            }catch{
            	InterruptedExceprion ie
            }
            buffer[in] = item;
            in = (in + 1) % BUFFER_SIZE;
            count++;
            notify();
        }
    }

    //Consumers call this method
    public synchronized E remove(){
    	E item;
        while(count == 0){ //๋ฒ„ํผ๊ฐ€ ๋น„์–ด์žˆ์œผ๋ฉด
        	try{
            	wait();
            }catch{
            	InterruptedException ie
            }
            item = buffer[out];
            out = (out + 1) % BUFFER_SIZE;
            count--;
            notify();
            return item;
        }
    }
}
  • ๋งŒ์•ฝ ํ•œ method๊ฐ€ synchronized๋กœ ์„ ์–ธ๋˜์–ด์žˆ๋‹ค๋ฉด, ๊ทธ method๋ฅผ ํ˜ธ์ถœํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ทธ object์— ๋Œ€ํ•œ lock์„ ์–ป์–ด์•ผ ํ•œ๋‹ค. 
  • ๋งŒ์•ฝ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ทธ lock์„ ์‹คํ–‰ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ํ˜ธ์ถœํ•œ ์Šค๋ ˆ๋“œ๋Š” ๊ทธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋๋‚ ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•ด์•ผ ํ•œ๋‹ค. 
  • Locks are released when the owning thread exits the synchronized method
  • ์ด์šฉ๋ถˆ๊ฐ€๋Šฅํ•œ lock์„ ์–ป๊ธธ ์‹œ๋„ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” ๊ฐ์ฒด์˜ entry set์— ๋“ค์–ด๊ฐ„๋‹ค. 
  • ๋งŒ์•ฝ lock์„ ๊ฐ€์ง„ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณ„์†ํ•  ์ˆ˜ ์—†์œผ๋ฉด wait()๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. 
    • ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ wait()ํ•จ์ˆ˜์„ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ:
      • ๊ทธ ์Šค๋ ˆ๋“œ๋Š” ๊ฐ์ฒด์— lock์„ ํ‘ผ๋‹ค. 
      • ๊ทธ ์Šค๋ ˆ์Šค์˜ ์ƒํƒœ๊ฐ€ '์ฐจ๋‹จ'์œผ๋กœ ์„ค์ •๋œ๋‹ค. 
      • ๊ทธ ์Šค๋ ˆ๋“œ๋Š” wait set์œผ๋กœ ๋ฐฐ์น˜๋œ๋‹ค. 
  • ์Šค๋ ˆ๋“œ๋Š” ๋Œ€๊ธฐํ•˜๊ณ  ์žˆ๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ๊นจ์šฐ๊ธฐ ์œ„ํ•ด notify()๋ฅผ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ๋‹ค. 
    • ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ notify()๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ:
      • ์ž„์˜์˜ ์Šค๋ ˆ๋“œ T๊ฐ€ wait set์œผ๋กœ ๋ถ€ํ„ฐ ์„ ํƒ๋œ๋‹ค. 
      • T๋Š” wait set์—์„œ entry set์œผ๋กœ ์ด๋™ํ•œ๋‹ค. 
      • T์˜ ์ƒํƒœ๋Š” ์ฐจ๋‹จ๋จ์—์„œ runnable์ƒํƒœ๋กœ ๋ฐ”๋€œ
    • ๊ทธ๋Ÿฌ๋ฉด T๋Š” ์ด์ œ condition์ด true์ธ์ง€ ํ™•์ธํ•˜๋Š” lock๋“ค๊ณผ ๊ฒฝ์Ÿํ•  ์ˆ˜ ์žˆ๋‹ค. 

2) Java Reentrant Locks

Reentrant Lock์€ mutex๋กœ ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. 

Lock key = new ReentrantLock();

key.lock();
try{
	//critical section
}finally{
	key.unlock();
}

์—ฌ๊ธฐ์„œ finally ๋ถ€๋ถ„์€ ์˜ˆ์™ธ๊ฐ€ try block์—์„œ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ์— lock์ด release ๋  ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•œ๋‹ค. 

 

3) Java Semaphores

  • Constructor
Semaphore(int value);
  • Usage
Semaphore sem = new Semaphore(1);

try{
    sem.acquire();
    //critical section
}
catch(InterruptedException ie){ }
finally{
    sem.release();
}

4) Java Condition Variables

  • Condition variables์€ ReentrantLock๊ณผ ๊ด€๋ จ์ด ์žˆ๋‹ค.
  • ReentrantLock์˜ 'newCondition()' method๋ฅผ ์ด์šฉํ•˜์—ฌ condition variable์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. 
Lock key = new ReentrantLock();
Condition condVar = key.newCondition();
  • ํ•œ ์Šค๋ ˆ๋“œ๋Š” 'await()'๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ ๋Œ€๊ธฐํ•˜๋ฉฐ, 'signal()' ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ ์‹ ํ˜ธ๋ฅผ ๋ณด๋‚ธ๋‹ค. 
  • Example
    • 0~4๊นŒ์ง€์˜ 5๊ฐ€์ง€ ์Šค๋ ˆ๋“œ๊ฐ€ ์กด์žฌํ•œ๋‹ค๊ณ  ํ•˜์ž. 
    • Shared variable์ธ 'turn'์ด ์กด์žฌํ•œ๋‹ค. ์ด๋Š” ์–ด๋–ค ์Šค๋ ˆ๋“œ์˜ ์ˆœ์„œ์ธ์ง€ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
    • ์Šค๋ ˆ๋“œ๋Š” ์–ด๋–ค ์ž‘์—…์„ ํ•˜๊ณ  ์‹ถ์„ ๋•Œ, dowork()๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. (ํ•˜์ง€๋งŒ ์ด๊ฒƒ์€ ์˜ค์ง ๊ทธ ์Šค๋ ˆ๋“œ์˜ ์ˆœ์„œ์ผ๋•Œ๋งŒ ๊ทธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๋‹ค. )
    • ๋งŒ์ผ ๊ทธ ์Šค๋ ˆ๋“œ์˜ turn์ด ์•„๋‹ˆ๋ผ๋ฉด ๋Œ€๊ธฐํ•œ๋‹ค.
    • ๋งŒ์•ฝ ๊ทธ ์Šค๋ ˆ๋“œ์˜ turn์ด๋ผ๋ฉด, ์ž ์‹œ ๊ทธ ์ผ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. 
    • ๊ทธ ์ผ์ด ๋๋‚ฌ๋‹ค๋ฉด, ๊ทธ ํ„ด์˜ ๋‹ค์Œ์ธ ์Šค๋ ˆ๋“œ์—๊ฒŒ notifyํ•œ๋‹ค. 
    • ํ•„์ˆ˜์ ์ธ data structure๋“ค์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
Lock key = new ReentrantLock();
Condition[] condVars = new Condition[5];
for(int i = 0; i < 5; i++)
	condVars[i] = lock.newCondition();
public void doWork(int threadNumber){
    lock.lock();

    try{
        //If it's not my turn, then wait until I'm signaled
        if(threadNumber != turn)
            condVars[threadNumbers].await();

        //Do some work for awhile...

        //Now signal to the next thread
        turn = (turn + 1) % 5;
        condVars[turn].signal();
    }
    catch(InterruptedException ie){ }
    finally{
        lock.unlock();
    }
    
}

 

5. Alternative Approaches(๋Œ€์•ˆ์  ์ ‘๊ทผ)

  • Memory transaction
    • ๋ถˆ๋Ÿฌ์˜ค๊ธฐ์™€ ์ €์žฅํ•˜๊ธฐ ๋ช…๋ น(a sequence of memory read-write operations)์˜ ์ง‘ํ•ฉ์ด atomicํ•˜๊ฒŒ ์ˆ˜ํ–‰๋  ์ˆ˜ ์žˆ๊ฒŒ ํ•จ์œผ๋กœ์„œ ๋ณ‘ํ–‰์„ฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๋‹จ์ˆœํ•˜๊ฒŒ ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. 
    • tramsaction์€ atomic{s}( S์— ์žˆ๋Š” statement๊ฐ€ atomicํ•˜๊ฒŒ ์‹คํ–‰๋˜๋„๋ก ๋ณด์žฅํ•ด์ฃผ๋Š”) ๋ฅผ ์ถ”๊ฐ€ํ•ด์คŒ์œผ๋กœ์จ ์‹คํ˜„๋  ์ˆ˜ ์žˆ๋‹ค.
//Tranditional implementation
void update(){
    acquire();
    /* modify shared data */
    release();
}

//Memory transaction-based implementation
void update(){
    atomic{
        /* modify shared data */
    }
}
  • OpenMP(Open Multi-Processing)
    • ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ ๋‹ค์ค‘ ์ฒ˜๋ฆฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ API๋กœ "#pragma omp critical"์„ ํฌํ•จ๋œ ์ฝ”๋“œ๋Š” critical section์œผ๋กœ ๋‹ค๋ค„์ง€๋ฉฐ atomicํ•˜๊ฒŒ ์ˆ˜ํ–‰๋œ๋‹ค. 
void update(int value){
    #pragma omp critical
    {
    	count += value;
    }
}

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

[Operating System] ์šด์˜์ฒด์ œ Caching [2]  (0) 2024.03.09
[Operating System] ์šด์˜์ฒด์ œ Caching [1]  (0) 2024.03.07
[์šด์˜์ฒด์ œ] Chapter6. Synchronization Tools(๋™๊ธฐํ™”)  (0) 2022.05.30
    'CS/Operating System' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
    • [Operating System] ์šด์˜์ฒด์ œ Caching [2]
    • [Operating System] ์šด์˜์ฒด์ œ Caching [1]
    • [์šด์˜์ฒด์ œ] Chapter6. Synchronization Tools(๋™๊ธฐํ™”)
    ๐Ÿธminzzi
    ๐Ÿธminzzi

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