빼미의 개발일기

[운영체제] - 31강. 동기화 기법 본문

프로그래밍/운영체제

[운영체제] - 31강. 동기화 기법

빼미01 2023. 11. 21. 13:19
이 글은 한빛미디어 '혼자 공부하는 컴퓨터 구조 + 운영체제'를 공부하고, 추가적인 부분을 찾아 정리한 내용입니다.


동기화를 위한 대표적인 도구,
뮤텍스, 세마포어, 모니터는 무엇인가?

 

● 뮤텍스 (Mutex : Mutual Exclusion)

- 상호 배제를 위한 동기화 도구, 동시에 접근해서는 안 되는 자원에 대해 동시 접근을 막는 장치. 락(Lock)이라고도 한다.

- 크리티컬 섹션에 진입한 프로세스(혹은 스레드)는 락(뮤텍스)을 걸어, 다른 프로세스의 접근을 막고, 자원을 이용하려는 프로세스는 락이 걸려 있다면 대기한다.

- 뮤텍스의 매우 단순한 형태는 하나의 전역 변수두 개의 함수로 구현할 수 있다.

  • 자물쇠 역할 : 프로세스(혹은 스레드)들이 공유하는 전역 변수 lock - 잠금상태인지를 체크하는 용도
  • 임계 구역을 잠그는 역할 : acquire 함수 - 프로세스가 크리티컬 섹션에 진입하기 전에 호출하는 함수
  • 임계 구역 잠금 해제 역할 : release 함수 - 크리티컬 섹션에서의 작업이 끝나고 호출하는 함수
acquire()
{
	while(lock == true)		// 만약 임계 구역이 잠겨 있다면
    ;					// 임계 구역이 잠겨 있는지를 반복적으로 확인
    lock = true;			// 만약 임계 구역이 잠겨 있지 않다면 임계 구역 잠금
}

release()
{
	lock = false; 			// 임계 구역 작업이 끝났으니 잠금 해제
}

 

- acquire() 와 release() 는 크리티컬 섹션 전후로 호출하여 하나의 프로세스만 임계 구역에 진입한다.

acquire();		// 자물쇠 잠겨 있는지 확인, 잠겨 있지 않다면 잠그고 들어가기
// 임계구역		// 임계 구역에서의 작업 진행
release();		// 자물쇠 반환

 

- acquire 함수는 크리티컬 섹션이 잠겨 있는지를 프로세스가 수시로 확인하는데, 이런 대기 방식을 바쁜 대기(Busy Waiting) 이라고 한다.

 

※ C/C++, python 등의 일부 프로그램은 뮤텍스 기능을 제공하며 훨씬 정교하게 설계되어 있다.

 


 

● 세마포어(Semaphore)

- 뮤텍스와 비슷하지만, 조금 더 일반화된 방식의 동기화 도구

- 공유 자원이 여러 개 있는 상황에서도 적용이 가능하도록 설계된 방식이다.

- 세마포어는 뮤텍스의 lock 변수처럼 잠김 표시와는 달리 크리티컬 섹션에 진입을 해도 된다, 안된다로 구분한다.

- 세마포어의 단순한 형태는 하나의 변수두 개의 함수로 구현할 수 있다.

  • 전역 변수 S : 크리티컬 섹션에 진입할 수 있는 프로세스의 개수 (사용 가능한 공유 자원의 개수)
  • wait 함수 : 크리티컬 섹션에 진입해도 되는지를 알려주는 함수
  • signal 함수 : 크리티컬 섹션 앞에서 기다리는 프로세스에게 진입해도 된다는 걸 알려주는 함수
각 S, wait, signal은 전공서마다 다를 수 있다. 일부 전공서에선 세마포어를 처음 개발한 에츠허르 다익스트라(Edsger W. Dijkstra)의 모국어에 근거하여 wait와 signal 함수를 P, V로 명명하기도 하고, 일부는 철도 신호기에 근거하여 down, up으로 명명하기도 한다.

 

wait()
// 임계 구역
signal()

 

- 변수 S는 크리티컬 섹션에 진입 가능한 프로세스의 개수, 혹은 사용 가능한 공유 자원의 개수이다.

wait()
{
	while(S <= 0)	// 만약 임계 구역에 진입할 수 있는 프로세스 개수가 0 이하라면
    ;			// 사용할 수 있는 자원이 있는지 반복적으로 확인
    S--;		// 진입할 수 있다면 S를 1감소 하고 임계 구역에 진입
}

 

signal()
{
	S++		// 임계 구역에서 작업을 마친 뒤 S를 1증가
}

 

- 위와 같은 방식의 코드로 세마포어를 만들면 임계 구역에 진입된 프로세스가 다 채워져있을 때 기다리는 프로세스는 바쁜대기(Busy Waiting)로 대기 해야 한다.

- 이를 개선 하는 방식으로 Block - WakeUp 방식을 고안했는데 이는 CPU 소모를 줄일 수 있다.

- 변수 S가 - (마이너스)로 넘어갔다면 진입하고자 하는 프로세스의 PCB를 세마포어를 위한 대기 큐에 집어넣고, 크리티컬 섹션의 작업이 끝나면 signal 함수를 호출하면서 대기중인 프로세스를 대기 큐에서 제거 후, 프로세스 상태를 준비 상태로 변경하고 준비 큐로 옮긴다.

wait()
{
	S--;
    if(S < 0)
    {
    	add this process to Queue;	// 해당 프로세스 PCB를 대기 큐에 삽입
        sleep();			// 대기 상태로 접어든다.
    }
}

 

signal()
{
	S++
    if(S <= 0)
    {
    	remove a process p from Queue	// 대기 큐에 있는 프로세스 p를 제거
        wakeup(p)			// 프로세스 p를 대기 상태에서 준비 상태로 만듬
    }
}

 

- 단 Block-WakeUp 방식은 프로세스를 WakeUp하는 과정에서 발생하는 오버헤드가 존재하기 때문에

  • 크리티컬 섹션 길이가 길면, Block / WakeUp 이 적당
  • 크리티컬 섹션 길이가 매우 짧다면, busy-waiting 가 적당

 

- 주의점 : 

wait, signal (혹은 P, V) 함수의 동작은 독립적이기 때문에 잘못 사용 하는 경우 문제가 발생한다. 타이밍 문제라고도 한다.

  • wait - 크리티컬 섹션 - wait : 현재 프로세스가 크리티컬 섹션에서 빠져 나갈 수 없게 된다. 또한 다른 프로세스들은 임계 구역에 들어갈 수 없기 때문에 교착 상태 (Dead Lock)가 발생한다.
  • signal - 크리티컬 섹션 - wait : 2개 이상의 프로세스가 동시에 크리티컬 섹션에 들어갈 수 있기 때문에, 상호 배제 (Mutual Exclusion)를 보장할 수 없게 된다.

 

● 모니터 (Monitor)

- 프로그래밍 언어 수준에서 동시성을 제어하여 타이밍 오류를 해결상호 배제 기법

- 세마포어 이론적 기반을 제공하고. 순차적으로만 사용할 수 있는 공유 자원 및 그룹을 할당한다.

- 공유 자원과 공유 자원에 접근하기 위한 인터페이스(통로)로 묶어 관리하며, 특정 조건을 바탕으로 프로세스를 실행하고 일시 중단하기 위한 조건 변수를 사용한다.

- 모니터 외부의 프로세스는 모니터 내부의 데이터를 직접 액세스 할 수 없으며, 한 순간에 하나의 프로세스만 모니터에 진입할 수 있다.

모니터 시각화

 

- 조건 변수는 wait, signal 두 가지 연산을 하며, 세마포어랑 원리는 비슷하다.

- 모니터에 진입한 프로세스 X가 wait()를 통해 조건 변수 x에 대한 큐에 진입한다면, 모니터는 비어있게 되므로 다음 프로세스 Y가 모니터에 진입하게 된다.

- 다른 프로세스의 signal()로 공유자원에 공간이 생기면 큐에 대기하던 프로세스를 깨우고 모니터 안에 진입한다.

 

※ 세마포어와 모니터 상세 상호관계

구분 세마포어 모니터
주체 OS, 개발자 주체 동시성 지원 프로그래밍 언어 수준 동시성
상호작용 모니터에 이론적 기반 제공
모니터에 효과적인 기법 제공
타이밍 오류 해결
개발 편의성 보완
특징 전역 변수 S의 타입에 따라 이진 / 계수
세마포어로 구분
한 시점에 하나의 프로세스만 모니터 내부에서 수행
세마포어와 계산 능력 동일
동기화
구현 사례
Semaphore S;
P(s); // 감소역할, s--
임계 구역()
V(s); // 증가 역할, s++

Monitor monitor-name
{
   public entry p1(...) {}
   public entry p2(...) {}
}

언어 사례 P, V 연산으로 구현 Java의 synchronized Objectm
.net의 모니터
공통점 동시성 지원을 위한 조정(Coordination) 기능 수행

 

 

 


 

※ 참고자료

https://velog.io/@octo__/%EB%AE%A4%ED%85%8D%EC%8A%A4Mutex

 

뮤텍스(Mutex)

뮤텍스란? 뮤텍스(Mutex)는 상호 배제(Mutual Exclusion)의 약자로 락(Lock)이라고도 한다.

velog.io

 

https://jwprogramming.tistory.com/13

 

Semaphore란? 세마포어와 뮤텍스의 차이는?

Deadlock에 이어, Semaphore와 mutex에 대해 설명하고자 합니다. - 프로세스 간 메시지를 전송하거나, 공유메모리를 통해 특정 데이터를 공유하게 되는 경우 문제가 발생할 수 있습니다. 즉, 공유된 자

jwprogramming.tistory.com

 

https://ko.wikipedia.org/wiki/%EC%84%B8%EB%A7%88%ED%8F%AC%EC%96%B4

 

세마포어 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 세마포어(Semaphore)는 에츠허르 데이크스트라가 고안한, 두 개의 원자적 함수로 조작되는 정수 변수로서, 멀티프로그래밍 환경에서 공유 자원에 대한 접근을 제

ko.wikipedia.org

 

https://velog.io/@octo__/%EC%84%B8%EB%A7%88%ED%8F%AC%EC%96%B4Semaphore

 

세마포어(Semaphore)

에츠허르 다익스트라(Edsger Wybe Dijkstra)가 제안한 교착 상태(DeadLock)에 대한 해법으로 두개의 원자적(Atomic) 함수로 제어되는 정수 변수로 멀티프로그래밍 환경에서 공유자원에 대한 접근 제어 방

velog.io

 

https://yoongrammer.tistory.com/65

 

Process synchronization: 모니터(monitor)

목차 Process synchronization: 모니터(monitor) 세마포어는 동시성 문제를 해결하는데 유용하지만 프로그래머가 올바르게 사용하지 않으면 타이밍 문제가 발생할 수 있습니다. 타이밍 문제란 타이밍에

yoongrammer.tistory.com

 

https://blog.skby.net/%EC%83%81%ED%98%B8-%EB%B0%B0%EC%A0%9C-%EA%B8%B0%EB%B2%95-%EB%AA%A8%EB%8B%88%ED%84%B0-monitor/

 

상호 배제 기법, 모니터 (Monitor) < 도리의 디지털라이프

I. 모니터의 개요 가. 모니터의 개념 프로그래밍 언어 수준에서 동시성을 제어하여 타이밍 오류를 해결한 상호 배제 기법 나. 모니터의 특징 세마포어의 이론적 기반 제공, 타이밍 오류와 P/V 연

blog.skby.net

 

Comments