운영체제

[운영체제] 프로세스 동기화 심화: 세마포어(Semaphore) 개념과 Java·Python 예제 코드

CodeCaine Explorer 2024. 12. 16. 10:50
728x90
반응형
SMALL

심화된 예제 🧠

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


자바 심화 예제 ☕

import java.util.concurrent.Semaphore;

public class ParkingLotExample {
    // 주차장(세마포어)
    private final Semaphore parkingSlots;

    public ParkingLotExample(int slots) {
        this.parkingSlots = new Semaphore(slots); // N개의 주차 슬롯
    }

    public void parkCar(String carName) {
        try {
            System.out.println(carName + " is trying to park.");
            parkingSlots.acquire(); // 주차장 입장 시도 🚗
            System.out.println(carName + " has parked. Available slots: " + parkingSlots.availablePermits());

            // 주차장에서 머무는 시간
            Thread.sleep((long) (Math.random() * 5000));

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            parkingSlots.release(); // 주차장 떠남 🚙
            System.out.println(carName + " has left. Available slots: " + parkingSlots.availablePermits());
        }
    }

    public static void main(String[] args) {
        ParkingLotExample parkingLot = new ParkingLotExample(3); // 3대 차량만 주차 가능

        // 여러 차량(스레드) 생성
        for (int i = 1; i <= 6; i++) {
            String carName = "Car-" + i;
            new Thread(() -> parkingLot.parkCar(carName)).start();
        }
    }
}
동작 설명 🚦
  1. 주차장 세마포어는 최대 3개의 차량만 동시에 주차 가능해요.
  2. parkingSlots.acquire()는 주차장에 빈자리가 있는지 확인하고, 빈자리가 없으면 대기 상태로 들어가요.
  3. parkingSlots.release()를 호출하면 주차장에서 나가고, 다른 차량이 들어올 수 있게 돼요.
  4. 총 6대의 차량이 있지만, 최대 3대만 주차 가능하기 때문에, 나머지는 대기 상태에 들어갑니다.

파이썬 심화 예제 🐍

import threading
import time
import random

# 주차장(세마포어)
parking_slots = threading.Semaphore(3)  # 3대 차량만 주차 가능

def park_car(car_name):
    print(f"{car_name} is trying to park.")
    with parking_slots:  # 세마포어 획득 (enter critical section)
        print(f"{car_name} has parked. Available slots: {parking_slots._value}")
        time.sleep(random.uniform(1, 5))  # 주차장에서 대기 시간 (1~5초 랜덤)
    print(f"{car_name} has left. Available slots: {parking_slots._value}")

# 여러 차량(스레드) 생성
threads = []
for i in range(1, 7):
    car_name = f"Car-{i}"
    t = threading.Thread(target=park_car, args=(car_name,))
    threads.append(t)
    t.start()

# 모든 스레드 종료 대기
for t in threads:
    t.join()
동작 설명 🚦
  1. threading.Semaphore(3)주차장을 3대 차량만 수용 가능하게 설정했어요.
  2. with parking_slots 블록에 들어가면, 세마포어의 슬롯을 하나 차지해요.
  3. 슬롯이 가득 차면, 남은 차량은 다른 차량이 떠날 때까지 대기 상태로 들어가요.
  4. time.sleep()으로 각 차량이 주차장에서 머무는 시간을 랜덤하게 설정했어요.

심화된 기능 및 사용법 ✨

  • 자원 제한 및 관리:
    세마포어는 이런 식으로 특정 리소스(예: 데이터베이스 연결, 쓰레드 풀) 사용을 제한할 때 매우 유용해요.
  • 동작 비교:
    자바 파이썬
    Semaphore.acquire() / Semaphore.release() with Semaphore (컨텍스트 매니저 사용 가능)
    직접 스레드 관리 (new Thread) threading.Thread
반응형
SMALL