๐Ÿ” Mutex, Semaphore, Monitor

์ตœํ˜ธ๋นˆยท2025๋…„ 2์›” 25์ผ
post-thumbnail

์ €๋ฒˆ ํฌ์ŠคํŒ…์—์„œ ์‹œ์Šคํ…œ ์ž์›์— ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค/์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋™๊ธฐํ™” ๋ฌธ์ œ์— ๋Œ€ํ•ด ์•Œ์•„๋ดค๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ๋™๊ธฐํ™” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋ฒ•์ธ ๋ฎคํ…์Šค(Mutex), ์„ธ๋งˆํฌ์–ด(Semaphore), ๋ชจ๋‹ˆํ„ฐ(Monitor)์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ  ๋น„๊ตํ•˜๊ณ ์ž ํ•œ๋‹ค.



๋ฎคํ…์Šค(Mutex)

๋ฎคํ…์Šค(Mutex, Mutual Exclusion)๋Š” ์ƒํ˜ธ ๋ฐฐ์ œ๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ, ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ๋˜๋Š” ์Šค๋ ˆ๋“œ๋งŒ์ด ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณด์žฅํ•˜๋Š” ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ž„๊ณ„ ์˜์—ญ(Critical Section)์„ ๋ณดํ˜ธํ•˜๊ณ  ๊ฒฝ์Ÿ ์ƒํƒœ(Race Condition)๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.



๋ฎคํ…์Šค์˜ ๊ตฌํ˜„ ์š”์†Œ

๋ฎคํ…์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์š”์†Œ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค:

  • acquire(): ๋ฎคํ…์Šค๋ฅผ ํš๋“ํ•˜๋Š” ํ•จ์ˆ˜.
  • release(): ๋ฎคํ…์Šค๋ฅผ ํ•ด์ œํ•˜๋Š” ํ•จ์ˆ˜.
  • available: ๋ฎคํ…์Šค์˜ ๊ฐ€์šฉ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถˆ๋ฆฌ์–ธ ๋ณ€์ˆ˜.

โ—๏ธ acquire() ์™€ release() ๋Š” ๋ฐ˜๋“œ์‹œ ์›์ž์ (Atomic)์œผ๋กœ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค.

์›์ž์  ์—ฐ์‚ฐ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด Compare-And-Swap(CAS) ์—ฐ์‚ฐ๊ณผ ๊ฐ™์€ ํ•˜๋“œ์›จ์–ด ๋ช…๋ น์–ด๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ์— ์ปดํ“จํ„ฐ๊ฐ€ ๋‹จ์ผ ์ฝ”์–ด๋ผ๋ฉด, ๊ทธ๋ƒฅ ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ Disable ์‹œํ‚ค๋ฉด ๊ฐ„๋‹จํ•˜๋‹ค.



๋ฎคํ…์Šค์˜ ๋™์ž‘ ๋ฐฉ์‹

#include <stdio.h>
#include <pthread.h>

#define ITERATIONS 10000  // ๋ฐ˜๋ณต ํšŸ์ˆ˜ ์ •์˜

int sum = 0;              // ๊ณต์œ  ๋ณ€์ˆ˜
pthread_mutex_t mutex;    // ๋ฎคํ…์Šค ์„ ์–ธ

// ์Šค๋ ˆ๋“œ ํ•จ์ˆ˜: sum์„ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ์—ญํ• 
void *counter(void *param) {
    for (int k = 0; k < ITERATIONS; k++) {
        // Entry section: ๋ฎคํ…์Šค ์ž ๊ธˆ
        pthread_mutex_lock(&mutex);

        // Critical section: ๊ณต์œ  ๋ณ€์ˆ˜ sum ์ฆ๊ฐ€
        sum++;

        // Exit section: ๋ฎคํ…์Šค ์ž ๊ธˆ ํ•ด์ œ
        pthread_mutex_unlock(&mutex);
    }
    pthread_exit(0);
}

int main() {
    pthread_t tid1, tid2;

    // ๋ฎคํ…์Šค ์ดˆ๊ธฐํ™”
    pthread_mutex_init(&mutex, NULL);

    // ๋‘ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ ์ƒ์„ฑ
    pthread_create(&tid1, NULL, counter, NULL);
    pthread_create(&tid2, NULL, counter, NULL);

    // ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    printf("sum = %d\n", sum);

    // ๋ฎคํ…์Šค ์ œ๊ฑฐ
    pthread_mutex_destroy(&mutex);
    return 0;
}
  1. ํ”„๋กœ์„ธ์Šค(๋˜๋Š” ์Šค๋ ˆ๋“œ)๋Š” ์ž„๊ณ„ ์˜์—ญ์— ๋“ค์–ด๊ฐ€๊ธฐ ์ „์— ๋ฎคํ…์Šค๋ฅผ ํš๋“(Acquire) ํ•ด์•ผ ํ•œ๋‹ค.
  2. ํ•ด๋‹น ํ”„๋กœ์„ธ์Šค(๋˜๋Š” ์Šค๋ ˆ๋“œ)๊ฐ€ ์ž„๊ณ„ ์˜์—ญ์„ ์‹คํ–‰ํ•œ๋‹ค.
  3. ์ž„๊ณ„ ์˜์—ญ์ด ๋๋‚˜๋ฉด ๋ฎคํ…์Šค๋ฅผ ํ•ด์ œ(Release) ํ•œ๋‹ค.
  4. ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค(๋˜๋Š” ์Šค๋ ˆ๋“œ)๊ฐ€ ๋ฎคํ…์Šค๋ฅผ ํš๋“ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ๋ฎคํ…์Šค๋ฅผ ํš๋“ํ•˜์ง€ ๋ชปํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ acquire() ํ•จ์ˆ˜์—์„œ ๋ฌดํ•œ ๋ฃจํ”„๋ฅผ ๋Œ๋ฉฐ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋ฐ”์œ ๋Œ€๊ธฐ(Busy Waiting) ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ๋ฐฉ์‹์€ ์žฅ์ ์ด ๋  ์ˆ˜ ์žˆ๋‹ค. ์ด ์žฅ์ ์„ ์‚ด๋ฆฐ ๋ฐฉ์‹์ด ์Šคํ•€๋ฝ(Spinlock)์ด๋‹ค.



์Šคํ•€๋ฝ(Spinlock)

๋ฎคํ…์Šค์˜ ํ•œ ํ˜•ํƒœ๋กœ ์Šคํ•€๋ฝ(Spinlock)์ด ์กด์žฌํ•œ๋‹ค. ์Šคํ•€๋ฝ์€ ๋ฎคํ…์Šค ์ž ๊ธˆ์„ ํš๋“ํ•  ๋•Œ๊นŒ์ง€ ๊ณ„์†ํ•ด์„œ CPU๋ฅผ ์ ์œ ํ•˜๋ฉด์„œ ๋ฃจํ”„๋ฅผ ๋Œ๋ฉฐ ๋Œ€๊ธฐํ•˜๋Š” ๋ฐฉ์‹์ธ, ์ฆ‰ Busy Waiting์„ ํ•˜๋Š” ๋ฎคํ…์Šค์ด๋‹ค.

์Šคํ•€๋ฝ์€ ๋ฐ”์œ ๋Œ€๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ํŠน์ • ์ƒํ™ฉ์—์„œ๋Š” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ๋‹ค. ๋ฌธ๋งฅ ๊ตํ™˜(Context Switch) ์—†์ด ๋™์ž‘ํ•˜๋ฏ€๋กœ, ์งง์€ ์‹œ๊ฐ„ ๋‚ด์— ๋ฎคํ…์Šค๋ฅผ ํš๋“ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์„ ๋•Œ ์œ ๋ฆฌํ•˜๋‹ค. ๋ฉ€ํ‹ฐ์ฝ”์–ด ์‹œ์Šคํ…œ์—์„œ๋Š” ํ•˜๋‚˜์˜ ์ฝ”์–ด์—์„œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฎคํ…์Šค๋ฅผ ํ•ด์ œํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์ฝ”์–ด์—์„œ ๋Œ€๊ธฐํ•˜๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฐ”๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์–ด ์Šคํ•€๋ฝ์ด ์˜คํžˆ๋ ค ๋” ์ข‹์€ ์„ ํƒ์ผ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์Šคํ•€๋ฝ์€ ๋‹จ์ผ ์ฝ”์–ด ์‹œ์Šคํ…œ์—์„œ๋Š” ๋น„ํšจ์œจ์ ์ด๋ฏ€๋กœ, ์ผ๋ฐ˜์ ์ธ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ฐ”์œ ๋Œ€๊ธฐ๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์„ธ๋งˆํฌ์–ด(Semaphore)๋‚˜ ์กฐ๊ฑด ๋ณ€์ˆ˜(Condition Variable)์™€ ๊ฐ™์€ ๋™๊ธฐํ™” ๊ธฐ๋ฒ•์„ ์ถ”๊ฐ€๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.





์„ธ๋งˆํฌ์–ด(Semaphore)

์„ธ๋งˆํฌ์–ด๋Š” Edsger Dijkstra๊ฐ€ ์ œ์•ˆํ•œ ๋™๊ธฐํ™” ๋„๊ตฌ๋กœ, ๋ฎคํ…์Šค์™€ ๋‹ฌ๋ฆฌ ๊ณต์œ  ์ž์›์— ๋™์‹œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค๋‚˜ ์Šค๋ ˆ๋“œ์˜ ์ˆ˜๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค. ์ถœ์ž… ๊ฐ€๋Šฅํ•œ ์ž๋™์ฐจ ์ˆ˜๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์ฃผ์ฐจ์žฅ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

์„ธ๋งˆํฌ์–ด(Semaphore) S๋Š” ์ •์ˆ˜ํ˜• ๋ณ€์ˆ˜์ด๋ฉฐ, ์ดˆ๊ธฐํ™” ์ดํ›„์—๋Š” ๋‘ ๊ฐ€์ง€ ์›์ž์  ์—ฐ์‚ฐ์ธ wait()๊ณผ signal() (ํ˜น์€ P()์™€ V())์„ ํ†ตํ•ด์„œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ P()์™€ V() ์—ฐ์‚ฐ์€ ๊ฐ๊ฐ ๋„ค๋œ๋ž€๋“œ์–ด์ธ Proberen(์‹œํ—˜ํ•˜๋‹ค)๊ณผ Verhogen(์ฆ๊ฐ€ํ•˜๋‹ค)์—์„œ ์œ ๋ž˜๋˜์—ˆ๋Š”๋ฐ, ์ด๋Š” Edsger Dijkstra๊ฐ€ ๋„ค๋œ๋ž€๋“œ์˜ ์ปดํ“จํ„ฐ ๊ณผํ•™์ž๋ผ ๊ทธ๋ ‡๋‹ค.



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

  1. ์ด์ง„ ์„ธ๋งˆํฌ์–ด(Binary Semaphore)
    • ๊ฐ’์ด 0๊ณผ 1 ์‚ฌ์ด์—์„œ๋งŒ ๋ณ€ํ•˜๋ฉฐ, 1์ธ ๊ฒฝ์šฐ ๋ฎคํ…์Šค์™€ ์œ ์‚ฌํ•˜๋‹ค.
  2. ์นด์šดํŒ… ์„ธ๋งˆํฌ์–ด(Counting Semaphore)
    • ๊ฐ’์ด 0 ์ด์ƒ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํŠน์ • ๊ฐœ์ˆ˜์˜ ๊ณต์œ  ์ž์› ๊ด€๋ฆฌ์— ์‚ฌ์šฉ๋œ๋‹ค.



์„ธ๋งˆํฌ์–ด์˜ ๋™์ž‘ ๋ฐฉ์‹(Busy - Wait ๋ฐฉ์‹)

์นด์šดํŒ… ์„ธ๋งˆํฌ์–ด๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ๊ณต์œ  ๋ณ€์ˆ˜ sum ์— ์ ‘๊ทผํ•˜๋Š” ์˜ˆ์‹œ์ด๋‹ค.
๋งŒ์•ฝ sem_init ์—์„œ 5 ๋Œ€์‹  1์„ ๋„ฃ๋Š”๋‹ค๋ฉด Binary Semaphore๊ฐ€ ๋œ๋‹ค.

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

int sum = 0; // ๊ณต์œ  ๋ณ€์ˆ˜
sem_t sem;

void *counter(void *param) {
    for (int k = 0; k < 10000; k++) {
        sem_wait(&sem); // ์„ธ๋งˆํฌ์–ด ๊ฐ์†Œ (์ง„์ž… ํ—ˆ์šฉ ๋Œ€๊ธฐ)
        sum++;
        sem_post(&sem); // ์„ธ๋งˆํฌ์–ด ์ฆ๊ฐ€ (์ž์› ๋ฐ˜ํ™˜)
    }
    pthread_exit(0);
}

int main() {
    pthread_t tid[5]; int i;
		sem_init(&sem, 0, 5);
		
		for (i = 0; i < 5; i++)
			pthread_create(&tid[i], NULL, counter, NULL);
			
		for (i = 0; i < 5; i++)
			pthread_join(tid[i], NULL);
			
		printf("sum = %d\n", sum);
    return 0;
}
  1. ์„ธ๋งˆํฌ์–ด๋ฅผ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ž์›์˜ ๊ฐœ์ˆ˜๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.
  2. ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž์›์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด wait()์„ ํ˜ธ์ถœํ•˜์—ฌ ์„ธ๋งˆํฌ์–ด ๊ฐ’์„ ๊ฐ์†Œ์‹œํ‚จ๋‹ค.
  3. ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž์›์„ ๋ฐ˜๋‚ฉํ•  ๋•Œ signal()์„ ํ˜ธ์ถœํ•˜์—ฌ ์„ธ๋งˆํฌ์–ด ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.
  4. ์„ธ๋งˆํฌ์–ด ๊ฐ’์ด 0์ด ๋˜๋ฉด, ์ถ”๊ฐ€์ ์ธ ํ”„๋กœ์„ธ์Šค๋Š” ์ž์›์ด ๋ฐ˜ํ™˜๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•œ๋‹ค.

๊ธฐ๋ณธ์ ์ธ ์„ธ๋งˆํฌ์–ด๋Š” ๋ฎคํ…์Šค์ฒ˜๋Ÿผ ๋ฐ”์œ ๋Œ€๊ธฐ(Busy Waiting) ๋ฌธ์ œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, Block - Wakeup ๋ฐฉ์‹์ด ์กด์žฌํ•œ๋‹ค.
wait() ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•œ ํ›„ ์ž์›์ด ์—†์œผ๋ฉด Busy Waiting์„ ํ•˜์ง€ ์•Š๊ณ (While๋ฌธ ๋Œ์ง€ ์•Š๊ณ ) ํ”„๋กœ์„ธ์Šค๋ฅผ ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ๋ณ€๊ฒฝํ•œ ํ›„ ๋Œ€๊ธฐ ํ(Waiting Queue)์— ์‚ฝ์ž…ํ•œ๋‹ค. ์ดํ›„ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ signal() ์—ฐ์‚ฐ์„ ํ˜ธ์ถœํ•˜๋ฉด ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ ๊ฐ€๋Šฅ ์ƒํƒœ(Ready Queue)๋กœ ์ด๋™์‹œํ‚จ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๋ฐ”์œ ๋Œ€๊ธฐ(Busy Waiting) ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

Busy-Wait VS Block-Wakeup

์ž„๊ณ„ ๊ตฌ์—ญ(Critical Section)์˜ ๊ธธ์ด๊ฐ€ ๊ธด ๊ฒฝ์šฐ๋Š” Block-Wakeup ๋ฐฉ์‹์ด ์œ ๋ฆฌํ•˜๋‹ค. ํ•˜์ง€๋งŒ ์ž„๊ณ„ ๊ตฌ์—ญ์ด ์งง๋‹ค๋ฉด ์žฆ์€ ๋ฌธ๋งฅ ๊ตํ™˜์œผ๋กœ ์ธํ•ด ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ Busy-Wait ๋ฐฉ์‹์ด ์œ ๋ฆฌํ•˜๋‹ค.



๋ฎคํ…์Šค vs ์„ธ๋งˆํฌ์–ด

์ด์ง„ ์„ธ๋งˆํฌ์–ด(Binary Semaphore)๋Š” 0๊ณผ 1๋งŒ ๊ฐ€์ง€๋Š” ์„ธ๋งˆํฌ์–ด๋กœ, ๋‹จ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ž„๊ณ„ ๊ตฌ์—ญ(๊ณต์œ  ์ž์›)์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œํ•œํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. ์ฆ‰, ๋ฎคํ…์Šค์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋ฎคํ…์Šค๋Š” ์„ธ๋งˆํฌ์–ด์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•˜๋„๋ก ํ—ˆ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด, ์™œ ๊ตณ์ด ๋ฎคํ…์Šค๋ฅผ ์‚ฌ์šฉํ• ๊นŒ?


๋ฎคํ…์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

  1. ์†Œ์œ  ๊ฐœ๋…์ด ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณด๋‹ค ์•ˆ์ „ํ•œ ๋™๊ธฐํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

    ์„ธ๋งˆํฌ์–ด๋Š” ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ wait()์„ ํ˜ธ์ถœํ•˜์—ฌ ์ž์›์„ ํš๋“ํ•œ ํ›„, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ signal()์„ ํ˜ธ์ถœํ•˜์—ฌ ์ด๋ฅผ ํ•ด์ œํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ด ๊ฒฝ์šฐ, ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ์‹ค์ˆ˜๋กœ ์ธํ•ด ์˜๋„์น˜ ์•Š๊ฒŒ ์ž์›์ด ํ•ด์ œ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜๋ฉด, ๋ฎคํ…์Šค๋Š” ์ด๋ฅผ ํš๋“ํ•œ ์Šค๋ ˆ๋“œ๋งŒ์ด ํ•ด์ œํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

  2. ๋ฐ๋“œ๋ฝ(Deadlock) ์œ„ํ—˜์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

    ์„ธ๋งˆํฌ์–ด๋Š” ์ง์ ‘ ์นด์šดํŠธ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋ฏ€๋กœ, wait()์„ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•˜๊ณ  signal()์„ ์ ์ ˆํžˆ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฐ๋“œ๋ฝ ์ƒํƒœ์— ๋น ์งˆ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฎคํ…์Šค๋Š” ๋‹จ์ˆœํžˆ "ํš๋“ โžก๏ธย ํ•ด์ œ"์˜ ํ˜•ํƒœ๋กœ ๋™์ž‘ํ•˜๋ฏ€๋กœ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์‹ค์ˆ˜ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์ค„์–ด๋“ ๋‹ค.

  3. ๋ช…ํ™•ํ•œ ์ƒํ˜ธ ๋ฐฐ์ œ(Mutual Exclusion)๋ฅผ ๋ณด์žฅํ•œ๋‹ค.

    ๋ฎคํ…์Šค๋Š” ์›๋ž˜ ๋ชฉ์ ์ด "ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•˜๋„๋ก ์ œํ•œํ•˜๋Š” ๊ฒƒ"์ด๋ฏ€๋กœ, ๊ณต์œ  ์ž์›์˜ ๋ณดํ˜ธ์— ์ตœ์ ํ™”๋˜์–ด ์žˆ๋‹ค. ๋ฐ˜๋ฉด, ์„ธ๋งˆํฌ์–ด๋Š” ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•˜๋Š” ์šฉ๋„๋กœ ์„ค๊ณ„๋œ ๋งŒํผ, ๋ฎคํ…์Šค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋„ ์ž˜๋ชป ์ ์šฉํ•˜๋ฉด ๋™๊ธฐํ™” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.


๊ทธ๋ ‡๋‹ค๋ฉด ์„ธ๋งˆํฌ์–ด๋Š” ์™œ ์‚ฌ์šฉํ• ๊นŒ?

๋ฎคํ…์Šค๊ฐ€ ๋ณด๋‹ค ์•ˆ์ „ํ•˜๊ณ  ์ง๊ด€์ ์ธ ๋™๊ธฐํ™” ๋ฐฉ์‹์„ ์ œ๊ณตํ•œ๋‹ค๋ฉด, ์„ธ๋งˆํฌ์–ด๋Š” ์™œ ์กด์žฌํ• ๊นŒ? ๊ทธ ์ด์œ ๋Š” ์„ธ๋งˆํฌ์–ด๊ฐ€ ๋™์‹œ ์ ‘๊ทผ์„ ์ œํ•œํ•˜๋Š” ๋ฐ ์œ ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ’€(DB Connection Pool)๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ๋ฅผ ์ƒ๊ฐํ•ด๋ณด์ž. ๋งŒ์•ฝ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์ตœ๋Œ€ 5๊ฐœ์˜ ๋™์‹œ ์—ฐ๊ฒฐ๋งŒ ํ—ˆ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด, ๋ฎคํ…์Šค๋กœ๋Š” ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด ํšจ์œจ์ด ๋–จ์–ด์ง„๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์„ธ๋งˆํฌ์–ด๋ฅผ ์ด์šฉํ•˜๋ฉด 5๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•˜๋„๋ก ์ œํ•œํ•  ์ˆ˜ ์žˆ์–ด ์ž์›์„ ๋ณด๋‹ค ํšจ์œจ์ ์œผ๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ํ•œ, IPC์—์„œ๋„ ์„ธ๋งˆํฌ์–ด๋Š” ์œ ์šฉํ•˜๋‹ค. ๋ฎคํ…์Šค๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ๋™์ž‘ํ•˜์ง€๋งŒ, ์„ธ๋งˆํฌ์–ด๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค ๊ฐ„ ์ž์› ์ ‘๊ทผ์„ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

IPC๊ฐ€ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด? ์—ฌ๊ธฐ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ž์„ธํžˆ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ๐Ÿค—

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



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

์„ธ๋งˆํฌ์–ด๋Š” ์œ ์—ฐํ•œ ๋™๊ธฐํ™” ๋„๊ตฌ์ด์ง€๋งŒ, ์‹คํ–‰ ์ˆœ์„œ๊ฐ€ ๊นจ์ง€๋Š” ๋“ฑ์˜ ํƒ€์ด๋ฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด,

  1. wait(mutex)์™€ signal(mutex)์˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊พธ๋ฉด ๋™๊ธฐํ™”๊ฐ€ ๊นจ์งˆ ์ˆ˜ ์žˆ๋‹ค.
    • Ex) ์ž„๊ณ„์˜์—ญ์— ๋™์‹œ์— ๋‘๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.
  2. signal()๋Œ€์‹  wait()๋กœ ์ž˜๋ชป ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ๋“œ๋ฝ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
  3. wait() ๋˜๋Š” signal()์„ ์ƒ๋žตํ•˜๋ฉด ๊ฒฝ์Ÿ ์ƒํƒœ(race condition)๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์€ ๋ชจ๋‘ ๊ฐœ๋ฐœ์ž๊ฐ€ ์„ธ๋งˆํฌ์–ด๋ฅผ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋А๋ƒ์— ๋”ฐ๋ผ ๋ฐœ์ƒํ•œ๋‹ค. ์ฆ‰, ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ์‹ค์ˆ˜๋กœ ์ธํ•ด ๋™๊ธฐํ™” ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๋”ฐ๋ผ์„œ ์„ธ๋งˆํฌ์–ด๋Š” ์ปค๋„ ๋ ˆ๋ฒจ์—์„œ ์šด์˜์ฒด์ œ(OS)์˜ ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ ์—ฌ์ „ํžˆ ์‚ฌ์šฉ๋˜์ง€๋งŒ, ์šฐ๋ฆฌ๊ฐ€ ์ ‘ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ ์ˆ˜์ค€์—์„œ๋Š” ์ง์ ‘์ ์ธ ์„ธ๋งˆํฌ์–ด๋ณด๋‹ค๋Š” ๋ชจ๋‹ˆํ„ฐ(Monitor) ๊ธฐ๋ฐ˜์˜ ๋™๊ธฐํ™” ๋„๊ตฌ๊ฐ€ ๋” ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.





๋ชจ๋‹ˆํ„ฐ(Monitor)

๋ชจ๋‹ˆํ„ฐ(Monitor)๋Š” ๋ฎคํ…์Šค(Mutex)๋‚˜ ์„ธ๋งˆํฌ์–ด(Semaphore)์™€ ๊ฐ™์€ ์ €์ˆ˜์ค€ ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ถ”์ƒํ™”ํ•˜์—ฌ ๋” ๋†’์€ ์ˆ˜์ค€์˜ ๋™๊ธฐํ™” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๊ฐœ๋…์ด๋‹ค. ์ด๋Š” ๊ณต์œ  ์ž์›์„ ์ž„๊ณ„ ๊ตฌ์—ญ์œผ๋กœ ๊ฐ์ถ”๊ณ , ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋งŒ์„ ์ œ๊ณตํ•จ์œผ๋กœ์จ ๋™๊ธฐํ™”๋ฅผ ๋ณด์žฅํ•œ๋‹ค. ์ฆ‰, ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ง์ ‘ ๋™๊ธฐํ™” ๊ธฐ๋ฒ•์„ ๋‹ค๋ฃจ์ง€ ์•Š๊ณ ๋„ ์•ˆ์ „ํ•˜๊ฒŒ ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

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



์กฐ๊ฑด ๋ณ€์ˆ˜ (Conditional Variables)

๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋‹ˆํ„ฐ๋งŒ์œผ๋กœ ๋ชจ๋“  ๋™๊ธฐํ™” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ํŠน์ • ์กฐ๊ฑด์ด ์ถฉ์กฑ๋  ๋•Œ๊นŒ์ง€ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์กฐ๊ฑด ๋ณ€์ˆ˜(Condition Variable)๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์กฐ๊ฑด ๋ณ€์ˆ˜๋Š” wait()์™€ signal() ์—ฐ์‚ฐ์„ ํ†ตํ•ด ๊ด€๋ฆฌ๋œ๋‹ค.

condition x, y;
x.wait(); // ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ์ „ํ™˜
x.signal(); // ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊นจ์›€
  • wait() : ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ์ „ํ™˜ํ•œ๋‹ค. ์ด๋Š” ์„ธ๋งˆํฌ์–ด์˜ P() ์—ฐ์‚ฐ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ, ์ž„๊ณ„ ๊ตฌ์—ญ์— ์ง„์ž…ํ•˜๋ ค๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์„ ํ–‰ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜์ง€ ๋ชปํ•  ๊ฒฝ์šฐ ๋Œ€๊ธฐํ•˜๋„๋ก ํ•œ๋‹ค.
  • signal() : ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊นจ์›Œ ์‹คํ–‰์„ ์žฌ๊ฐœํ•˜๋„๋ก ํ•œ๋‹ค. ์ด๋Š” ์„ธ๋งˆํฌ์–ด์˜ V() ์—ฐ์‚ฐ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋ฉฐ, ์ž„๊ณ„ ๊ตฌ์—ญ์ด ๋น„์–ด ์ƒˆ๋กœ์šด ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.



๊ณต์œ  ์ž์›์ธ ์€ํ–‰ ๊ณ„์ขŒ ์ž”์•ก(balance)์„ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋‹ˆํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์˜ˆ์‹œ๋กœ ๋“ค์–ด๋ณด์ž.

(์ถœ์ฒ˜ : https://velog.io/@chappi/OS๋Š”-ํ• ๊ป€๋ฐ-ํ•ต์‹ฌ๋งŒ-ํ•ฉ๋‹ˆ๋‹ค.-8ํŽธ-Critical-section-์ž„๊ณ„-๊ตฌ์—ญ2-mutex-semaphore-monitor-condition-variable)

monitor shared_balance {
    private:
        int balance = 10;
        boolean busy = false;
        condition mon;

    public:
        increase(int amount) {
            if (busy == true) mon.wait(); // ์ž„๊ณ„ ๊ตฌ์—ญ์ด ์‚ฌ์šฉ ์ค‘์ด๋ฉด ๋Œ€๊ธฐ
            busy = true; // ์ž„๊ณ„ ๊ตฌ์—ญ ์ง„์ž…
            balance = balance + amount; // ๊ณต์œ  ์ž์› ์ˆ˜์ •
            mon.signal(); // ๋‹ค์Œ ๋Œ€๊ธฐ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค ๊นจ์›€
        }
}

์ด ์ฝ”๋“œ์—์„œ increase() ํ•จ์ˆ˜๋Š” busy ํ”Œ๋ž˜๊ทธ๋ฅผ ํ™•์ธํ•˜์—ฌ ์ž„๊ณ„ ๊ตฌ์—ญ์ด ์‚ฌ์šฉ ์ค‘์ธ์ง€ ์ฒดํฌํ•œ๋‹ค. ๋งŒ์•ฝ ์ด๋ฏธ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž„๊ณ„ ๊ตฌ์—ญ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค๋Š” mon.wait()์„ ํ˜ธ์ถœํ•˜์—ฌ ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ์ „ํ™˜๋œ๋‹ค. ๋ฐ˜๋Œ€๋กœ, ์ž„๊ณ„ ๊ตฌ์—ญ์ด ๋น„์–ด ์žˆ๋‹ค๋ฉด busy๋ฅผ true๋กœ ์„ค์ •ํ•˜๊ณ  balance๋ฅผ ๊ฐฑ์‹ ํ•œ ๋’ค, mon.signal()์„ ํ˜ธ์ถœํ•˜์—ฌ ๋Œ€๊ธฐ ์ค‘์ธ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊นจ์šด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ํ”„๋กœ์„ธ์Šค P1๊ณผ P2๊ฐ€ increase() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. P1์ด ๋จผ์ € ์‹คํ–‰๋˜๊ณ , balance = balance + amount ์ˆ˜ํ–‰ ๋„์ค‘ ํƒ€์ž„ ์Šฌ๋กฏ์ด ๋๋‚˜๊ฒŒ ๋œ๋‹ค๋ฉด, P2๊ฐ€ increase()๋ฅผ ์‹คํ–‰ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•  ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ busy๊ฐ€ true์ด๋ฏ€๋กœ P2๋Š” mon.wait()์„ ํ˜ธ์ถœํ•˜๊ณ  ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ๋“ค์–ด๊ฐ„๋‹ค. ์ดํ›„ P1์ด ์ž‘์—…์„ ๋งˆ์น˜๊ณ  mon.signal()์„ ํ˜ธ์ถœํ•˜๋ฉด, P2๊ฐ€ ๋Œ€๊ธฐ ํ์—์„œ ๊นจ์–ด๋‚˜ ์‹คํ–‰์„ ์ด์–ด๊ฐˆ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

๋ชจ๋‹ˆํ„ฐ๋Š” ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๋™๊ธฐํ™”๋ฅผ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด์„œ ๋ถˆํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์ˆจ๊ธฐ๊ณ , ๊ณต์œ  ์ž์›์— ๋Œ€ํ•œ ๋ช…ํ™•ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ์„ ์ œ๊ณตํ•œ๋‹ค. ์ด๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ์˜ ์ •๋ณด ์€๋‹‰(Information Hiding) ๊ฐœ๋…๊ณผ๋„ ์œ ์‚ฌํ•˜๋‹ค.



๋ฎคํ…์Šค vs ๋ชจ๋‹ˆํ„ฐ

๋จผ์ €, ๋ฎคํ…์Šค๋Š” ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๋‚˜ ์Šค๋ ˆ๋“œ ๊ฐ„ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค. ์ฆ‰, ์šด์˜์ฒด์ œ ์ปค๋„์ด ์ œ๊ณตํ•˜๋Š” ๋ฝ(Lock) ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ, ์„œ๋กœ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์—์„œ๋„ ๊ณต์œ  ์ž์›์„ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณดํ˜ธํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์šด์˜์ฒด์ œ ์ฐจ์›์˜ ๋™๊ธฐํ™” ๊ธฐ๋Šฅ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฌด๊ฒ๊ณ  ์„ฑ๋Šฅ์ด ๋‹ค์†Œ ๋А๋ฆฌ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

๋ฐ˜๋ฉด, ๋ชจ๋‹ˆํ„ฐ๋Š” ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ์Šค๋ ˆ๋“œ ๊ฐ„ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•ด ์ œ๊ณต๋œ๋‹ค. ์šด์˜์ฒด์ œ ์ˆ˜์ค€์ด ์•„๋‹ˆ๋ผ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ๋™๊ธฐํ™” ๊ธฐ๋Šฅ์ด๋ฉฐ, ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฎคํ…์Šค๋ฅผ ํ™œ์šฉํ•˜์ง€๋งŒ ๋” ๋†’์€ ์ˆ˜์ค€์˜ ์ถ”์ƒํ™”๋œ ๊ฐœ๋…์ด๋‹ค. ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ Java์—์„œ synchronized, wait(), notify() ๋“ฑ์„ ์ด์šฉํ•œ ๋™๊ธฐํ™” ๋ฐฉ์‹์ด ์žˆ๋‹ค.

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



์„ธ๋งˆํฌ์–ด vs ๋ชจ๋‹ˆํ„ฐ

์„ธ๋งˆํฌ์–ด๋Š” ์นด์šดํ„ฐ ๊ธฐ๋ฐ˜ ๋™๊ธฐํ™” ๊ธฐ๋ฒ•์œผ๋กœ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๊ฐ’์„ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ง์ ‘ wait()๊ณผ signal()์„ ์‚ฌ์šฉํ•ด ์นด์šดํŠธ ๊ฐ’์„ ์กฐ์ž‘ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๊ด€๋ฆฌ๊ฐ€ ๋ฒˆ๊ฑฐ๋กœ์šธ ์ˆ˜ ์žˆ๋‹ค.

๋ฐ˜๋ฉด, ๋ชจ๋‹ˆํ„ฐ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์บก์Аํ™”ํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๋ฝ์„ ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. Java์—์„œ๋Š” ๋ชจ๋“  ๊ฐ์ฒด๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, synchronized ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž๋™์œผ๋กœ ๋ฝ์„ ํš๋“ํ•˜๊ณ  ํ•ด์ œํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ๋˜ํ•œ, wait(), notify(), notifyAll() ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ํ˜‘๋ ฅ์ ์ธ ๋™๊ธฐํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

๋˜ํ•œ, ๋ชจ๋‹ˆํ„ฐ๋Š” ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ๋งŒ ๋™์ž‘ํ•˜๋Š” ๋ฐ˜๋ฉด, ์„ธ๋งˆํฌ์–ด๋Š” ๋‹ค์ค‘ ํ”„๋กœ์„ธ์Šค ํ™˜๊ฒฝ์—์„œ๋„ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ฐจ์ด์ ์ด ์žˆ๋‹ค. ์ฆ‰, ๋ชจ๋‹ˆํ„ฐ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹จ์ผ ํ”„๋กœ์„ธ์Šค์˜ ์Šค๋ ˆ๋“œ ๋™๊ธฐํ™”์— ์ดˆ์ ์„ ๋งž์ถ”๊ณ  ์žˆ์œผ๋ฉฐ, ์„ธ๋งˆํฌ์–ด๋Š” ์šด์˜์ฒด์ œ ์ฐจ์›์—์„œ ํ”„๋กœ์„ธ์Šค ๊ฐ„ ๋™๊ธฐํ™”(IPC)๊นŒ์ง€ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋‹ค.



+) Java์˜ ๋ชจ๋‹ˆํ„ฐ ๊ธฐ๋Šฅ

  • synchronized ํ‚ค์›Œ๋“œ
    • ํŠน์ • ์ฝ”๋“œ ๋ธ”๋ก(์ž„๊ณ„์˜์—ญ)์— ๋Œ€ํ•ด ๋ชจ๋‹ˆํ„ฐ ๋ฝ์„ ์ ์šฉ
    • synchronized (object) { // ์ž„๊ณ„์˜์—ญ }
    • ๋ฉ”์„œ๋“œ ์ „์ฒด์— ์ ์šฉ ๊ฐ€๋Šฅ โ†’ public synchronized void method() {}
  • wait()์™€ notify() ๋ฉ”์„œ๋“œ
    • wait(): ํ˜„์žฌ ์Šค๋ ˆ๋“œ ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ๋งŒ๋“ฆ
    • notify(): ๋Œ€๊ธฐ ์ค‘์ธ ์Šค๋ ˆ๋“œ ์ค‘ ํ•˜๋‚˜๋ฅผ ๊นจ์›€
    • notifyAll(): ๋Œ€๊ธฐ ์ค‘์ธ ๋ชจ๋“  ์Šค๋ ˆ๋“œ๋ฅผ ๊นจ์›€





+) ๋ผ์ด๋ธŒ๋‹ˆ์Šค(Liveness)

๋ผ์ด๋ธŒ๋‹ˆ์Šค(Liveness)๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ์–ธ์  ๊ฐ€๋Š” ๋ฐ˜๋“œ์‹œ ์ง„ํ–‰๋  ์ˆ˜ ์žˆ์Œ์„ ๋ณด์žฅํ•˜๋Š” ์„ฑ์งˆ์„ ์˜๋ฏธํ•œ๋‹ค. ์ฆ‰, ์‹œ์Šคํ…œ์ด ๊ต์ฐฉ ์ƒํƒœ(Deadlock)๋‚˜ ๋ฌดํ•œ ๋Œ€๊ธฐ(Starvation) ์—†์ด ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜๋„๋ก ํ•˜๋Š” ๊ฐœ๋…์ด๋‹ค.

+) ์„ธ๋งˆํฌ์–ด๋‚˜ ๋ชจ๋‹ˆํ„ฐ๋Š” ๋ฐ๋“œ๋ฝ๊ณผ ๊ธฐ์•„ ํ˜„์ƒ์„ ํ•ด๊ฒฐํ•ด์ฃผ์ง€ ๋ชปํ•œ๋‹ค.

๋ฐ๋“œ๋ฝ(Deadlock)

  • ๋‘ ๊ฐœ ์ด์ƒ์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์„œ๋กœ์˜ ์ž์›์„ ๊ธฐ๋‹ค๋ฆฌ๋ฉด์„œ ์˜์›ํžˆ ๋ฉˆ์ถ”๋Š” ์ƒํƒœ

์šฐ์„ ์ˆœ์œ„ ์—ญ์ „(Priority Inversion)

  • ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž์›์„ ์ ์œ ํ•˜๋ฉด์„œ ๋†’์€ ์šฐ์„ ์ˆœ์œ„ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋Œ€๊ธฐ





์ฐธ๊ณ  ์ž๋ฃŒ

[์ง€๊ธˆ ๋ฌด๋ฃŒ]์šด์˜์ฒด์ œ ๊ณต๋ฃก์ฑ… ๊ฐ•์˜ ๊ฐ•์˜ | ์ฃผ๋‹ˆ์˜จ - ์ธํ”„๋Ÿฐ

[OS] ๋™๊ธฐํ™” ๋ฌธ์ œ

OS๋Š” ํ• ๊ป€๋ฐ ํ•ต์‹ฌ๋งŒ ํ•ฉ๋‹ˆ๋‹ค. 9ํŽธ Critical section (์ž„๊ณ„ ๊ตฌ์—ญ2) , mutex, semaphore, monitor, condition variable

[์šด์˜์ฒด์ œ] ์„ธ๋งˆํฌ์–ด(semaphore) ๋ฎคํ…์Šค(mutex) ๋ชจ๋‹ˆํ„ฐ(Monitor)

[OS] 4. ํ”„๋กœ์„ธ์Šค ๋™๊ธฐํ™” (Process Synchronization)

1๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2025๋…„ 3์›” 13์ผ

์—ด์‹ฌํžˆ ์ฝ์—ˆ๋Š”๋ฐ ๋ญ”์†Œ๋ฆฐ์ง€๋ฅผ ๋„ํ†ต ๋ชจ๋ฅด๊ฒ ๊ตฐ์š”.. ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.. ํ”„๋กœ์„ธ์Šค ์Šค๋ ˆ๋“œ๋Š” ์ž˜ ์ฝ์—ˆ์–ด์š”..

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ