운영체제

[운영체제] 프로세스 동기화 완벽 정리: Mutex, Semaphore 개념과 자바·파이썬 예제

CodeCaine Explorer 2024. 12. 18. 09:34
728x90
반응형
SMALL

프로세스 동기화란? 🧩

"프로세스 동기화"는 여러 프로세스(또는 스레드)가 동시에 같은 공유 자원에 접근할 때, 문제가 발생하지 않도록 제어하는 기술이에요.
문제가 생기는 이유는 경쟁 상태(Race Condition) 때문이에요.

경쟁 상태란? 🏁

  • 경쟁 상태는 여러 스레드가 동시에 자원에 접근해서, 원치 않는 결과를 초래하는 상황이에요.
  • 예를 들어, 두 사람이 동시에 ATM에서 같은 계좌를 수정하려고 한다고 상상해 보세요! 😱
    • A가 잔액을 수정하려는 중간에 B가 덮어쓰면 잘못된 결과가 나올 수 있죠.

해결 방법 🛠️

문제를 방지하려면 뮤텍스(Mutex)세마포어(Semaphore) 같은 동기화 메커니즘을 사용해요.

뮤텍스(Mutex) 🛡️

뮤텍스는 "서로 배타적인(Mutual Exclusion)"이라는 뜻이에요.
한 번에 하나의 스레드만 자원을 사용할 수 있도록 잠금(Lock)을 걸어줘요.

  • 예: 열쇠가 하나 있는 화장실! 🚪
    • 열쇠를 가진 사람만 들어갈 수 있고, 나올 때 열쇠를 돌려줘야 해요.

세마포어(Semaphore) 🚦

세마포어는 뮤텍스보다 조금 더 유연해요.

  • 동시에 N개의 스레드가 자원을 사용할 수 있도록 허용할 수 있어요.
  • 예: 주차장! 🅿️
    • 5대의 차만 들어올 수 있는 주차장이 있다면, 자리가 찼을 때는 대기해야 해요.

예제: 자바와 파이썬 코드 🎯

자바 예제 ☕

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

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

    // 뮤텍스 락 생성
    private final Lock lock = new ReentrantLock();

    // 동기화된 메서드
    public void increment() {
        lock.lock(); // 잠금! 🔒
        try {
            counter++; // 공유 자원 수정
            System.out.println(Thread.currentThread().getName() + " incremented to " + counter);
        } finally {
            lock.unlock(); // 잠금 해제! 🔓
        }
    }

    public static void main(String[] args) {
        CounterExample example = new CounterExample();

        // 여러 스레드 생성
        Runnable task = example::increment;

        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);

        t1.start();
        t2.start();
    }
}
동작 설명 🧠
  1. 두 개의 스레드(t1, t2)가 동시에 공유 자원(counter)를 수정하려고 시도해요.
  2. lock.lock()을 호출하면 뮤텍스가 활성화되어 한 스레드만 접근할 수 있어요.
  3. 작업이 끝나면 lock.unlock()으로 다른 스레드에게 자원을 넘겨줘요.

파이썬 예제 🐍

import threading

# 공유 자원 (Counter)
counter = 0

# 뮤텍스 락 생성
lock = threading.Lock()

# 동기화된 함수
def increment():
    global counter
    lock.acquire()  # 잠금! 🔒
    try:
        counter += 1  # 공유 자원 수정
        print(f"{threading.current_thread().name} incremented to {counter}")
    finally:
        lock.release()  # 잠금 해제! 🔓

# 여러 스레드 생성
thread1 = threading.Thread(target=increment)
thread2 = threading.Thread(target=increment)

thread1.start()
thread2.start()

thread1.join()
thread2.join()
동작 설명 🧠
  1. 전역 변수 counter에 동시에 접근하려는 두 스레드(thread1, thread2)가 있어요.
  2. lock.acquire()를 호출하면 하나의 스레드만 작업할 수 있도록 잠금을 걸어요.
  3. 작업이 끝나면 lock.release()로 다른 스레드가 작업을 시작하게 해요.

한눈에 보는 차이점 👀

구분 뮤텍스(Mutex) 세마포어(Semaphore)
동시 접근 한 번에 1개만 가능 N개의 스레드가 동시에 접근 가능
예제 상황 화장실(열쇠 1개) 주차장(주차 가능 공간 여러 개)

 

2024.12.16 - [운영체제] - [프로세스 동기화] 세마포어 심화 예제 : 예시 코드

 

[세마포어]심화 예제 : 예시 코드

심화된 예제 🧠이번에는 세마포어(Semaphore)를 사용해 여러 스레드가 제한된 수의 자원을 동시에 사용하는 심화 예제를 다뤄볼게요.예를 들어, 3대의 차량만 동시에 주차할 수 있는 주차장을 구

alswnsghd1234.tistory.com

 

2023.03.30 - [운영체제] - 프로세스와 스레드의 차이 : 쉬운 설명

 

프로세스와 스레드의 차이 : 쉬운 설명

1. 기본 정의프로세스(Process): 실행 중인 프로그램의 독립적인 단위.비유: 여러 개의 독립된 공장에서 각자 다른 물건을 생산.스레드(Thread): 프로세스 안에서 실행되는 작은 작업 단위.비유: 하나

alswnsghd1234.tistory.com

 

반응형
SMALL