Computer Science/Operating System

공유자원과 경쟁 상태, 임계영역

settong 2024. 10. 31. 20:20
반응형

공유 자원 (Shared Resource)

공유자원이란 시스템 안에서 각 프로세스, 스레드가 함께 접근할 수 있는 자원을 말한다.

 

공유 자원의 특징

  • 다중접근
    여러 프로세스나 스레드가 동시에 접근할 수 있기 때문에 관리가 필요.
  • 데이터 일관성
    올바르게 관리되지 않으면 데이터 일관성이 깨질 수 있음
  • 동기화 필요
    여러 접근을 조율하기 위한 동기화 매커니즘 필요

공유 자원의 예시

  • 여러 스레드가 동시에 접근하는 전역변수
  • 여러 프로세스가 동시에 접근하는 파일
  • 메모리, 파일, 데이터베이스...

 

 

경쟁 상태 (Race Condition)

두개 이상의 프로세스나 스레드가 공유 자원에 동시에 접근할 때 발생하는 문제.

동시에 접근을 시도할 때 타이밍이 예상되는 결과 값에 영향을 줄 수 있는 상태.

 

이를 잘 해결하지 못하면 데이터 정합성, 데이터 무결성을 지키지 못할 수 있음.

  • 데이터 정합성: 예상되는 데이터값과 다른 것 (0원으로 읽어야 하는데 1000원으로 읽음)
  • 데이터 무결성 : 데이터의 규칙을 위반하면 안되는 것. (0원인데 출금 함)

 

 

임계 영역 (Critical Section)

공유 자원에 접근하는 코드의 특정 부분을 의미. 이 영역은 한번에 하나의 프로세스나 스레드만 접근할 수 있도록 해야한다.

 

임계 영역의 특징

  • 상호 배제: 임계 영역에 한 번에 하나의 프로세스나 스레드만 진입할 수 있도록 보장해야 합니다.
  • 잠금 메커니즘: 뮤텍스, 세마포어 등의 동기화 메커니즘을 사용하여 임계 영역을 보호합니다.
  • 성능 고려: 너무 많은 잠금은 성능 저하를 초래할 수 있으므로 적절하게 설계해야 합니다.

예시 코드 (Java)

두 개의 스레드가 동시에 공유 자원에 접근하여 counter 변수를 증가시키는 상황을 다뤄보자.

synchronized 키워드를 사용하여 임계 영역을 보호할 수 있다!

public class Counter {
    private int counter = 0; // 공유자원

	// increment() 메서드에 synchronized를 사용하여 임계영역 보호
    public synchronized void increment() {
        counter++;
    }

    public int getValue() {
        return counter;
    }

    public static void main(String[] args) {
        Counter counter = new Counter(); // Counter 객체 생성

		// 두개의 스레드 생성하고 CounterRunnable 실행
        Thread thread1 = new Thread(new CounterRunnable(counter));
        Thread thread2 = new Thread(new CounterRunnable(counter));
        thread1.start();
        thread2.start();

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Final counter value: " + counter.getValue());
    }
}


class CounterRunnable implements Runnable {
    private final Counter counter;

    public CounterRunnable(Counter counter) {
        this.counter = counter; // 생성자 호출: Counter 객체를 받아서 저장
    }

    @Override
    public void run() {
        for (int i = 0; i < 100000; i++) {
            counter.increment(); // increment()메서드를 호출하여 counter 값 증가.
        }
    }
}

최종적으로 counter 값은 200,000이다. 여기서 중요하게 살펴야 할 것은 synchronized 키워드를 사용하여 increment() 메서드를 임계 영역으로 보호한다는 것이다.

728x90
반응형