본문 바로가기

CS/운영체제

동기화

임계 영역

- 하나의 프로세스가 수정 가능한 공유 자원을 액세스 하고 있을 때, 그 프로세스에 의해 참조되는 프로그램의 부분을 의미한다.

- 하나의 프로세스가 공유 데이터를 접근하면, 다른 프로세스는 그 공유 데이터를 접근해서는 안 된다. 즉 여러 프로세스들 중에 하나의 프로세스만이 임계 영역을 사용할 수 있도록 하여 임계 영역에서 공유 변수 값의 무결성을 보장한다.

- 임계 영역을 수행 중에 있는 프로세스는 인터럽트, 교착상태, 무한반복이 발생하지 않도록 해야 한다.

코드 지역

- 프로세스가 임계 영역에 진입하려면 진입허가를 요청해야 하는데, 이런 요청을 구현하는 코드 부분을 진입 역역이라고 한다.

- 임계 영역을 사용한 이후에는 임계 영역을 빠져나왔음을 알리는 진출 영역이 있다. 나머지 코드 부분은 잔류 영역이라고 한다.

요구조건

상호배제(Mutual Exclusion)

- 한 프로세스가 공유 기억장치 혹은 공유 파일을 사용하고 있을 때, 다른 프로세스들이 사용하지 못하도록 배제시키는 제어 기법이다.

- 임계 영역의 개념을 이용하여 두 프로세스가 하나의 공유 자원을 상호 배타적으로 사용할 수 있게 하면서 동시에는 수행할 수 없도록 하는 것이다.

제한된 대기(Bounded waiting)

- 어떤 프로세스도 제한된 대기를 한 뒤에는 임계 영역으로 진입할 수 있어야 한다는 뜻이다. , 프로세스가 세마포어 내에서 무한히 기다리는 바쁜 대기를 방지한다.

- 어떤 프로세스가 임계 영역 진입을 요청하면 다른 프로세스들의 임계 영역 진입 허용 횟수에 제한을 두어야한다.

진행 조건

- 임계 구역을 실행하는 프로세스가 없고, 임계 영역으로 진입하려는 프로세스들이 있다면, 이들 중 어느 하나만 선택되어 자신의 임계 영역으로 진입할 수 있어야 하며, 이 선택이 무한정 연기될 수 없도록 해야 한다.

동기화 기법

뮤텍스(Mutex)

- 특정 프로세스(스레드)가 공유 자원을 사용하고 있는 상황이라면, 다른 프로세스가 공유 자원을 사용하지 못하도록 하는 동기화 기법이다.

- 공유 자원 점유한 프로세스는 락(Lock)을 지니며, 자원 사용을 마치면 락을 반납한다.

public class mutex {
	static boolean islock;

	private static void lock() {
		while(!islock) {
			if(islock)
				break;
		}
		islock = true;
	}
	
	private static void unlock() {
		islock = false;
	}
	
	public static void main(String[] args) {
		lock();
		/*
		 * Critical Section
		 */
		unlock();
	}
}

세마포어(Semaphore)

- 각 프로세스에 제어 신호를 전달하여 순서대로 작업을 수행하도록 하는 동기화 기법이다.

- 세마포어에 대한 연산은 처리 도중에 인터럽트 되어서는 안 된다. 즉 여러 프로세스가 동시에 세마포어의 값을 수정할 수 없다.

- 프로세스 사이의 동기를 유지하고 상호배제의 원리를 보장할 수 있다.

- 세마포어 SPV 연산으로만 접근 가능한 카운터 변수이며, 0 이상의 값을 가질 수 있다.

- S의 값이 01로만 제한되면 이진 세마포어(Binary semaphore)이며, 그 이상의 값을 가지면 카운팅 세마포어(Counting semaphore)이다.

P 연산 : Wait 동작 / 자원을 사용하려는 프로세스들의 진입 여부를 자원 카운트(S)를 통해 결정한다. 카운트를 감소시켜서(S--) 자원 점유를 알린다.
V 연산 : Signal 동작 / 대기 중인 프로세스를 깨우는 신호이다. 카운트를 증가시켜서(S++) 자원 반납을 알린다.
wait(s) : if (s>0) s = s-1; // wait(s) 연산은 진입 영역
           else 현재의 프로세스를 블록하고 대기 큐에 추가
signal(s) : if(1개 이상의 프로세스가 s에서 대기 중이면) 그 중 한 개 프로세스만 진행
            else s = s+1; // signal(s)연산은 진출 영역
import java.util.LinkedList;
import java.util.Queue;

public class semaphore {
	static int S = 3;
	static Queue<Integer> q = new LinkedList<Integer>();

	private static void waitS(int s) {
		if (s > 0)
			S--;
		else {
			q.offer(1);
		}
	}

	private static void signalS(int s) {
		if (!q.isEmpty()) {
			q.poll();
		} else
			S++;
	}
	
	public static void main(String[] args) {
		waitS(S);
		/*
		 * Critical Section
		 */
		signalS(S);
	}
}

뮤텍스와 세마포어의 차이점

- Binary semaphore를 통해 Mutex를 구현할 수 있지만, MutexSemaphore를 구현할 수는 없다.

- 키가 하나만 쓸 수 있나 여러 개 쓸 수 있나의 차이다.

모니터(Monitor)

- 뮤텍스는 다른 프로세스간에 동기화 할 때 사용하고 모니터는 하나의 프로세스 내에서 다른 스레드 간의 동기화에 사용된다

- 모니터는 프레임워크나 라이브러리 그 자체에서 제공된다. C언어에는 없고 Java에는 있다.

- 모니터는 일련의 동기화 작업들이 캡슐화되어 있어서 synchronized, wait(), notify()등의 키워드를 통해 좀 더 편하게 동기화 할 수 있다. 

세마포어와 모니터의 차이

- 세마포어에 비해서 모니터 쪽이 공유자원에 접근할 수 있는 키의 획득과 해제를 모두 처리해서 간단하다.

- 세마포어는 직접 키해제와 공유자원 접근 처리를 해주어야한다.

- 달리 말해 세마포어는 귀찮게 임계구역 앞에 wait을 설정하고 끝나고 signal을 설정해줘야 하지만 모니터는 그럴 필요 없이 함수 앞에 synchronized를 붙여주기만 하면 알아서 상호배제하여 함수의 작업을 수행한다.

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

가상화란? (VM, 컨테이너, 도커, 쿠버네티스)  (0) 2021.03.24
교착상태(Deadlock)  (0) 2021.03.03
캐시(Cache)  (0) 2021.02.27
멀티 프로세스  (0) 2021.02.24