동기화

SeungJoo
|2024. 3. 15. 23:22
728x90

동기화

동기화는 다수의 프로세스나 스레드에서 공유 자언에 동시에 접근할 때 발생할 수 있는 문제를 해결하기 위한 기술입니다.

여러 프로세스나 스레드가 동시에 공유 자원을 수정하거나 읽을 때, 일관된 순서로 접근하여 데이터의 일관성 보장의 목표

프로세스 동기화

컴퓨터 시스템에서 여러 프로세스가 동시에 실행될 때 발생할 수 있는 문제를 해결하는 기술입니다.

 

동기화의 목적

상호 배제

동일한 자원에 대해 여러 프로세스나 스레드가 동시에 접근하지 못하도록 제어하는 것을 말하며, 즉, 한 프로세스나 스레드가 자원을 사용하고 있을 때에는 다른 프로세스나 스레드는 접근할 수 없도록 해야 합니다.

예를 들면, 계좌에 저축하는 프로세스 A와 B가 있을 때 A가 자원을 사용하는 동안 B는 대기하고, A작업이 끝난 후에 B가 자원에 접근하는 방식으로 이렇게 함으로 충돌을 방지하고 안전하게 자원을 사용할 수 있습니다.

 

순서 보장

동기화를 통해 어떤 프로세스나 스레가 자원에 접근할 때 순서를 보장하여 일관성을 유지하는 것을 말하며 예를 들면, 여러 프로세스나 공유 자원에 접근하게 되는데 먼저 요청한 프로세스가 먼저 접근할 수 있도록 순서를 정하는 것이 해당됩니다.

 

동기화 구분 방법

뮤텍스, 세마포어, 모니터등으로 동기화 기법으로, 공유 자원에 대한 접근을 조절하고 상호 배제를 보장하는 데 사용합니다.

 

뮤텍스

뮤텍스는 상호배제를 위한 동기화 메커니즘 중 하나로, 오직 하나의 스레드만이 특정 자원에 접근할 수 있도록 하는 동기화 객체입니다. 뮤텍스는 임계 영역에 진입하기 전에 락을 획득하고, 임계영역을 벗어날 때 락을 해제하여 다른 스레드가 접근할 수 있도록 합니다.

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AccountExample {
    private static int balance = 100000;  // 초기 계좌 잔액
    private static Lock mutex = new ReentrantLock();  // 뮤텍스 생성

    public static void depositMoney(int amount) {
        mutex.lock();  // 뮤텍스 락 획득
        try {
            balance += amount;  // 잔액 증가
        } finally {
            mutex.unlock();  // 뮤텍스 락 해제
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // A 스레드: 2만 원을 입금
        Thread threadA = new Thread(() -> {
            depositMoney(20000);
        });

        // B 스레드: 5만 원을 입금
        Thread threadB = new Thread(() -> {
            depositMoney(50000);
        });

        // 두 개의 스레드 실행
        threadA.start();
        threadB.start();

        // 메인 스레드가 두 스레드의 작업을 기다림
        threadA.join();
        threadB.join();

        // 잔액 출력
        System.out.println("잔액: " + balance + "원");
    }
}

 

세마포어

세마포어는 뮤텍스와 유사하게 상호배제를 제공하지만, 뮤텍스와는 다르게 동시에 여러 개의 스레드 임계 영역에 진입할 수 있도록 허용하는 카운팅 기반의 동기화 객체입니다. 세마포어는 허용 가능한 스레드의 개수를 제어하는 카운터 역할도 합니다.

import java.util.concurrent.Semaphore;

public class AccountExample {
    private static int balance = 100000;  // 초기 계좌 잔액
    private static Semaphore semaphore = new Semaphore(1);  // 세마포어 생성 (허용 가능한 스레드 개수: 1)

    public static void depositMoney(int amount) throws InterruptedException {
        semaphore.acquire();  // 세마포어 획득
        try {
            balance += amount;  // 잔액 증가
        } finally {
            semaphore.release();  // 세마포어 해제
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // A 스레드: 2만 원을 입금
        Thread threadA = new Thread(() -> {
            try {
                depositMoney(20000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // B 스레드: 5만 원을 입금
        Thread threadB = new Thread(() -> {
            try {
                depositMoney(50000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 두 개의 스레드 실행
        threadA.start();
        threadB.start();

        // 메인 스레드가 두 스레드의 작업을 기다림
        threadA.join();
        threadB.join();

        // 잔액 출력
        System.out.println("잔액: " + balance + "원");
    }
}

 

모니터

고급 프로그래밍 언어에서 제공되는 추상화된 동기화 메커니즘입니다. 모니터는 임계 영역에 대한 접근을 제어하고 상호배제를 구현하며, 스레드 간의 통신을 돕는다는 것은 뮤텍스와 유사하지만 좀 더 추상화된 형태로 제공됩니다. 또한 모니터는 언어에 따라 구현이 다를 수 있지만, 대부분 임계 영역에 진입하기 위한 키워드나 메서드를 제공하여 사용합니다.

 

 

 

 

 

 

728x90

'운영체제' 카테고리의 다른 글

CPU 스케줄링  (0) 2023.10.09
프로세스와 스레드  (0) 2023.09.07
운영체제  (0) 2023.08.16