CS 공부 & 면접 맛보기 0x0C [운영체제] : Race Condition을 방지하는 방법

2025. 1. 13. 23:00코딩 도구/CS 면접 도구

반응형

Race Condition을 제어하는 방법

질문

Race Condition을 방지하는 방법은 무엇인가요?

면접 답변

Race Condition(경쟁 상태)은 여러 스레드가 동시에 동일한 자원에 접근할 때 발생하는 문제입니다. 이를 방지하기 위해 다음과 같은 동기화 기법을 사용할 수 있습니다:

  • 뮤텍스(Mutex): 한 번에 하나의 스레드만 자원에 접근할 수 있도록 잠금(lock)을 제공하는 동기화 도구입니다.
  • 세마포어(Semaphore): 제한된 수의 스레드만 동시에 자원에 접근할 수 있도록 합니다.
  • 모니터(Monitor): 객체 수준의 동기화 도구로, 특정 객체에 대한 스레드 접근을 제어합니다.
  • 원자적 연산(Atomic Operations): 특정 연산을 한 번에 수행하여, 실행 중간에 다른 스레드의 개입을 방지하는 기법입니다.

이제 각 방법을 좀 더 자세히 설명드리겠습니다.


1. 뮤텍스(Mutex)

원리

  • 상호 배제(Mutual Exclusion)를 보장하는 도구입니다.
  • 한 번에 하나의 스레드만 자원에 접근할 수 있습니다.

C++ 코드 예제

#include <iostream>
#include <thread>
#include <mutex>
using namespace std;

mutex mtx;
int counter = 0;

void increment() {
    for (int i = 0; i < 10000; ++i) {
        mtx.lock();
        counter++;
        mtx.unlock();
    }
}

int main() {
    thread t1(increment);
    thread t2(increment);

    t1.join();
    t2.join();

    cout << "Final Counter Value: " << counter << endl;
    return 0;
}

장단점

  • 장점: 간단하고 사용하기 쉬움.
  • 단점: 성능 저하 (락 경쟁 발생 가능).

2. 세마포어(Semaphore)

원리

  • 동시에 여러 스레드가 자원에 접근할 수 있도록 허용하는 동기화 도구입니다.
  • 제한된 수의 스레드만 접근 가능합니다.

C++ 코드 예제

#include <iostream>
#include <thread>
#include <semaphore>
using namespace std;

int counter = 0;
counting_semaphore<1> sem(1);

void increment() {
    for (int i = 0; i < 10000; ++i) {
        sem.acquire();
        counter++;
        sem.release();
    }
}

int main() {
    thread t1(increment);
    thread t2(increment);

    t1.join();
    t2.join();

    cout << "Final Counter Value: " << counter << endl;
    return 0;
}

장단점

  • 장점: 동시에 여러 스레드를 허용할 수 있음.
  • 단점: 구현이 복잡할 수 있음.

3. 원자적 연산(Atomic Operations)

원리

  • 원자적 연산은 특정 연산을 한 번에 수행하여, 실행 도중 다른 스레드가 해당 연산을 방해할 수 없게 합니다.
  • 이를 위해 하드웨어 수준의 명령어를 활용하여 연산이 불가분하게 수행되도록 보장합니다.

C++ 코드 예제

#include <iostream>
#include <thread>
#include <atomic>
using namespace std;

atomic<int> counter(0);

void increment() {
    for (int i = 0; i < 10000; ++i) {
        counter.fetch_add(1);
    }
}

int main() {
    thread t1(increment);
    thread t2(increment);

    t1.join();
    t2.join();

    cout << "Final Counter Value: " << counter.load() << endl;
    return 0;
}

특징 및 장단점

  • 특징: std::atomic은 내부적으로 메모리 배리어(Memory Barrier)를 사용하여 연산이 중단 없이 실행되도록 합니다.
  • 장점: 간편하고 빠름.
  • 단점: 복잡한 연산에는 부적합하며, 단순한 정수 증가/감소 연산에 주로 사용됨.

4. 모니터(Monitor)

원리

  • 객체 수준의 동기화 도구로, 자원에 대한 독점 접근을 제공합니다.
  • Java에서 synchronized 키워드를 사용하여 구현됩니다.

장단점

  • 장점: 객체 단위로 접근을 제어.
  • 단점: 세밀한 제어가 어려울 수 있음.

Race Condition 방지 기법 비교표

기법설명사용성성능

뮤텍스하나의 스레드만 자원 접근 허용쉬움느림
세마포어제한된 수의 스레드만 접근 허용중간중간
원자적 연산특정 연산을 중단 없이 수행쉬움빠름
모니터객체 단위의 동기화 제공쉬움느림

결론

  • Race Condition은 공유 자원에 여러 스레드가 동시 접근할 때 발생할 수 있습니다.
  • 이를 방지하기 위해 뮤텍스, 세마포어, 원자적 연산, 모니터 등의 동기화 기법을 사용할 수 있습니다.
  • 상황에 맞는 동기화 방식을 선택하는 것이 중요합니다.
반응형