[OS] 동기화 메커니즘(Synchronization Mechanisms)(2): 모니터(Monitor)

2023. 11. 21. 21:30· Computer Science/Operating System
목차
  1. 💋 인트로
  2. 💋 모니터(Monitor)
  3. ✔️ 개념
  4. ✔️ 동작 원리
  5. ✔️ Queue
  6. 💋 Bounded buffer problem
  7. ✔️ 구성
  8. ✔️ 목표
  9. 💋 Monitor in Java
  10. ✔️ 모니터 동작
  11. ✔️ 자바로 구현한 Bounded buffer problem
  12. 💋 아웃트로
  13. 💋 참고자료
반응형
반응형

 

 

 

💋 인트로

지난 포스팅에 이어, 스레드 동기화 메커니즘 중 하나인 모니터에 대해 설명하겠습니다.

 

💋 모니터(Monitor)

✔️ 개념

 

baeldung의 모니터에 대한 글을 보면, 모니터를 아래와 같이 정의합니다.

 

출처: https://www.baeldung.com/cs/monitor

 

 

모니터는 mutual exclusion과 cooperation을 통해 스레드 간의 안전한 공유자원 접근을 보장하는데 사용됩니다.

 

  • mutual exclusion ⇒ 동시에 하나의 스레드만 진입해서 실행 가능
  • cooperation ⇒ 조건에 따라 스레드가 대기 상태로 전환 가능

 

스레드가 어떤 공유자원에 접근하는 것을 말 그대로 모니터할 수 있기 때문에 모니터라고 부른다고 합니다.

 

✔️ 동작 원리

 

모니터는 뮤텍스와 condition variable로 구성되어 있으며, waiting queue와 entry queue를 통해 스레드들을 관리합니다.

 

condition variable과 관련된 주요 동작은 아래와 같습니다.

  • wait: 스레드가 자기 자신을 condition variable의 waiting queue에 넣고 대기 상태로 전환합니다.
  • signal: waiting queue에서 대기중인 스레드 중 하나를 깨웁니다.
  • broadcast: waiting queue에서 대기중인 스레드 전부를 깨웁니다.

 

코드로 이해해 봅시다!

 

acquire(mutexLock);						   // 뮤텍스 락 취득 -> 락 취득 못하면 entry queue에서 대기

while (!p) {								  // 조건 확인 -> 조건이 충족되지 않으면 waiting queue에서 대기
	wait(mutexLock, conditionVariable);		 
}

// ...

signal(conditionVariable2);					// 앞의 conditionVariable과 다를 수도 있음.
// broadcast(conditionVariable2);

release(mutexLock);							// 뮤텍스 락 반환

 

위 코드는 대충의 뼈대이고, 각각을 실행하는 과정을 풀어서 설명하면 아래와 같습니다.

 

  • acquire(mutexLock);
    • 뮤텍스 락을 취득하지 못한 스레드는 entry queue에서 대기하게 됩니다.
  • 조건 확인
    • mutexLock 이 파라미터인 이유 ⇒ 대기 상태로 전환된 스레드가 뮤텍스 락을 가지고 있으면 다른 스레드들이 뮤텍스 락을 취득할 수 없기 때문에, wait를 호출과 함께 락을 반환하기 위해서입니다.
    • conditionVariable 이 파라미터인 이유 ⇒ conditionVariable 별로 waiting queue를 가지고 있기 때문입니다.
    • 조건이 충족되지 않은 스레드는 wait(mutexLock, conditionVariable); 호출해 waiting queue에서 대기하게 됩니다.
  • 조건까지 확인된 스레드는 자신의 할 일을 수행하는데, 이 코드는 위에서 …입니다.
  • signal(conditionVariable2);
    • 어떤 waiting queue의 스레드를 깨울지 그 condition variable을 통해서 관리할 수 있습니다.
    • conditionVariable2은 앞서 등장한 conditionVariable와 반드시 같을 필요는 없습니다.
    • broadcast를 사용하는 경우에는 conditionVariable2를 통해 관리하는 waiting queue에 있는 스레드 모두를 깨울 수 있습니다.
    • conditionVariable2를 통해 관리하는 waiting queue에 있는 스레드 중 하나를 깨웁니다.

 

 

이때 등장하는 두 가지 Queue를 정리해보면 다음과 같습니다.

✔️ Queue

  • entry queue: 뮤텍스 락을 취득하기 위해 기다리는 큐
  • waiting queue: 조건이 충족되길 기다리는 큐

 

 

💋 Bounded buffer problem

(Producer-Consumer Problem이라고도 합니다.)

 

하나의 문제 예시를 설명하고, 앞서서 열심히 공부한 모니터를 사용해서 이 문제를 어떻게 해결할 수 있는지 보여드리겠습니다.

 

✔️ 구성

 

이미지 출처: https://www.baeldung.com/cs/bounded-buffer-problem

 

 

  • Producer: 데이터를 생성하는 역할
  • Consumer: 데이터를 소비하는 역할
  • Buffer: 데이터가 저장되고, 공유되는 공간인데, limited capacity

 

✔️ 목표

  • Producer는 버퍼가 꽉 찼을 때 더이상 데이터를 생산하지 않습니다.
  • Consumer는 이미 소비한 데이터를 또 소비하지 않습니다.
  • Buffer는 제한된 capacity를 효율적으로 사용합니다.

 

모니터를 사용해서 이 목표를 이룰 수 있습니다.

 

이미지 출처: https://www.youtube.com/watch?v=Dms1oBmRAlo&list=PLcXyemr8ZeoQOtSUjwaer0VMJSMfa-9G-&index=6

 

Producer, Consumer는 Buffer를 공유해서 사용하기 때문에, Buffer에 접근할 때는 critical section 안에서, mutual exclusion이 보장된 상태여야만 합니다.

 

Producer, Consumer 코드에서 공통적으로 lock.acquire(), lock.release() 사이의 부분은 critical section이 됩니다.

 

Producer의 스레드는 Buffer가 다 찼다면(q.isFull()), wait를 하게 됩니다. Consumer 스레드가 데이터를 소비한 후에 signal()을 호출해 Producer의 스레드가 깨어날 수 있게 됩니다. Producer 스레드는 데이터를 생산한 후에 signal()을 호출해서 Consumer의 스레드를 깨울 수 있습니다.

 

Producer 스레드는 자신의 작업을 완료한 후 Consumer 스레드를 깨우고,

Consumer 스레드는 자신의 작업을 완료한 후 Producer 스레드를 깨웁니다. (크로스!!!)

 

💋 Monitor in Java

자바의 모든 객체는 내부적으로 모니터를 가집니다.

자바의 모니터의 mutual exclusion 기능은 synchronized 키워드로 사용할 수 있으며, condition variable은 딱 하나만 가집니다.

 

✔️ 모니터 동작

자바 모니터는 세 가지 동작이 가능합니다.

  • wait
  • notify → signal()과 동일
  • notifyAll → broadcast()과 동일

 

✔️ 자바로 구현한 Bounded buffer problem

 

public class BoundedBuffer {

	private final int[] buffer = new int[5];
	private int count = 0;

	public synchronized void produce(int item)  {
		while (count == 5) {
			try {
				wait();
			} catch (InterruptedException e) {
				throw new RuntimeException(e);
			}
		}
		buffer[count++] = item;
		notifyAll();
	}

	public void consume() {
		int item = 0;
		synchronized (this) {
			while (count == 0) {
				try {
					wait();
				} catch (InterruptedException e) {
					throw new RuntimeException(e);
				}
			}
			item = buffer[--count];
			notifyAll();
		}
	}
}

 

 

produce(), consume()의 두 메서드가 동시에 실행되지 않도록 하기 위해 synchroized 키워드를 통해 mutual exclusion을 보장합니다.

synchroized 키워드는 메서드에 붙일 수도 있고, 메서드 내부의 block에서만 사용할 수도 있습니다.

synchroized 을 block으로 사용하는 경우에 파라미터를 전달해 주어야 하는데, 이 파라미터를 통해 뮤텍스 락을 전달해주어야 합니다.

this는 객체 자신을 가리는데, 이걸 통해 뮤텍스 락을 전달할 수 있을까요?

 

자바의 모든 객체는 모니터를 가지고 있고 그 모니터에는 뮤텍스 락이 있기 때문에 this를 전달하는 것은 뮤텍스 락을 전달한다는 의미와 동일합니다.

 

wait(), notifyAll()은 자신의 객체가 속한 모니터의 condition variable에 대한 동작입니다. wait()과 notifyAll()은 synchronized 메서드 또는 블록 내에서 호출되어야 합니다.

위의 예제에서는 여러 개의 condition variable이 사용되었기 때문에, 각 조건에 따라 다른 condition variable을 파라미터로 함께 사용했는데, 자바에서는 딱 1개의 condition variable만을 가지기 때문에 별도로 condition variable을 파라미터로 보내지는 않습니다.

 

public class Main {

	public static void main(String[] args) throws InterruptedException {
		final BoundedBuffer boundedBuffer = new BoundedBuffer();

		final Thread consumer = new Thread(() -> boundedBuffer.consume());
		final Thread producer = new Thread(() -> boundedBuffer.produce(100));

		consumer.start();
		producer.start();

		consumer.join();
		producer.join();

		System.out.println("Bounded Buffer Test Done.");
	}
}

 

여러 번 시도하더라도, 항상 Producer가 데이터를 생산한 후에야 Consumer가 데이터를 소비하기 때문에, 어쨌든 Consumer가 100이라는 데이터를 소비한 후에 종료되는 것을 확인할 수 있습니다.

 

 

이외에도 java.util.concurrent에는 동기화 기능이 탑재된 여러 클래스가 있으니, 안심하고 사용할 수 있습니다.

 

 

💋 아웃트로

 

오늘 포스팅을 작성하면서 나름대로의 언어로 정리한 후에 GPT 선생님의 검토를 받았는데, 극찬을 받았어요ㅋㅋ

 

 

💋 참고자료

  • https://www.baeldung.com/cs/monitor
  • https://www.baeldung.com/cs/bounded-buffer-problem
  • https://binaryterms.com/producer-consumer-problem.html
  • https://stackoverflow.com/questions/3362303/whats-a-monitor-in-java
  • https://www.youtube.com/watch?v=Dms1oBmRAlo&list=PLcXyemr8ZeoQOtSUjwaer0VMJSMfa-9G-&index=7

 

 

도움이 되었다면, 공감/댓글을 달아주면 깃짱에게 큰 힘이 됩니다!🌟
비밀댓글과 메일을 통해 오는 개인적인 질문은 받지 않고 있습니다. 꼭 공개댓글로 남겨주세요!

 

 

반응형

'Computer Science > Operating System' 카테고리의 다른 글

[OS] OS, Java에서 프로세스의 상태 (State of Process in OS and Java)  (0) 2023.11.23
[OS] 데드락(Deadlock)은 언제 발생하고, OS, Java에서 어떻게 해결할까?  (1) 2023.11.22
[OS] 동기화 메커니즘(Synchronization Mechanisms)(1): 스핀락(Spinlock), 뮤텍스(Mutex), 세마포어(Semaphore)  (0) 2023.11.20
[OS] 동기화(synchronization)의 필요성: 경쟁 조건(race condition), 임계 영역(critical section)  (0) 2023.11.12
[OS] CPU Bound VS IO Bound: 스레드는 몇 개가 좋을까?  (0) 2023.11.10
  1. 💋 인트로
  2. 💋 모니터(Monitor)
  3. ✔️ 개념
  4. ✔️ 동작 원리
  5. ✔️ Queue
  6. 💋 Bounded buffer problem
  7. ✔️ 구성
  8. ✔️ 목표
  9. 💋 Monitor in Java
  10. ✔️ 모니터 동작
  11. ✔️ 자바로 구현한 Bounded buffer problem
  12. 💋 아웃트로
  13. 💋 참고자료
'Computer Science/Operating System' 카테고리의 다른 글
  • [OS] OS, Java에서 프로세스의 상태 (State of Process in OS and Java)
  • [OS] 데드락(Deadlock)은 언제 발생하고, OS, Java에서 어떻게 해결할까?
  • [OS] 동기화 메커니즘(Synchronization Mechanisms)(1): 스핀락(Spinlock), 뮤텍스(Mutex), 세마포어(Semaphore)
  • [OS] 동기화(synchronization)의 필요성: 경쟁 조건(race condition), 임계 영역(critical section)
깃짱
깃짱
연새데학교 컴퓨터과학과 & 우아한테크코스 5기 백엔드 스타라이토 깃짱
반응형
깃짱
깃짱코딩
깃짱
전체
오늘
어제
  • 분류 전체보기
    • About. 깃짱
    • Weekly Momentum
      • 2024
    • PROJECT
      • AIGOYA LABS
      • Stamp Crush
      • Sunny Braille
    • 우아한테크코스5기
    • 회고+후기
    • Computer Science
      • Operating System
      • Computer Architecture
      • Network
      • Data Structure
      • Database
      • Algorithm
      • Automata
      • Data Privacy
      • Graphics
      • ETC
    • WEB
      • HTTP
      • Application
    • C, C++
    • JAVA
    • Spring
      • JPA
      • MVC
    • AI
    • MySQL
    • PostgreSQL
    • DevOps
      • AWS
      • 대규모 시스템 설계
    • frontend
      • HTML+CSS
    • NextJS
    • TEST
    • Industrial Engineering
    • Soft Skill
    • TIL
      • 2023
      • 2024
    • Linux
    • Git
    • IntelliJ
    • ETC
      • 日本語

블로그 메뉴

  • 홈
  • 깃허브

인기 글

최근 글

태그

  • 상속
  • 상속과조합
  • 컴포지션
  • 우아한테크코스5기
  • lamda
  • OOP
  • 함수형프로그래밍
  • Stream
  • 스트림
  • 조합
  • 우테코
  • 레벨로그
  • 람다
  • TDD
  • 우아한테크코스
  • Composition
  • 람다와스트림
  • 우테코5기
  • 예외
  • Java
hELLO · Designed By 정상우.v4.2.0
깃짱
[OS] 동기화 메커니즘(Synchronization Mechanisms)(2): 모니터(Monitor)
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.