프로세스는 서로 메세지를 보내고 프로세스 내부에서는 스레드끼리 자원을 공유하면서 동기화에 대한 문제가 항상 발생할 수 있다. 즉, 공유된 자원에 여러 프로세스, 여러 스레드가 동시에 접근하면서 문제가 발생한다.
Critical Section은 멀티 프로세스 환경에서 둘 이상의 프로세스가 동시에 접근해서는 안되는 공유 자원의 코드 영역이다. C.S은 시간이 지나면 종료되며, 어떤 프로세스가 C.S에 접근하기 위해서는 지정된 시간만큼 대기해야 한다.
이 때 스레드나 프로세스가 배타적인 사용권을 보장받기 위해서 세마포어 같은 동기화 메커니즘이 사용된다.
C.S에서 발생하는 문제들은 3가지 조건을 충족시키면 해결할 수 있다.
1. Mutual Exclustion(상호 배제) - 하나의 프로세스가 C.S에 들어가 있으면 다른 프로세스는 들어갈 수 없다.
2. Progress(진행) - C.S에 들어간 프로세스가 없다면, 어느 프로세스가 들어갈 것인지 적절히 선택해줘야 한다,
3. Bounded Waiting(한정 대기) - 기아상태를 방지하기 위해, 한 번 들어갔다 나온 프로세스는 다음에 들어갈 때 제한을 준다.
1. Lock
하드웨어 기반 해결책으로써, 동시에 공유 자원에 접근하는 것을 막기 위해 Critical Section 에 진입하는 프로세스는 Lock 을 획득하고 Critical Section 을 빠져나올 때, Lock 을 방출함으로써 동시에 접근이 되지 않도록 한다.
2. 세마포어
세마포어는 동시에 리소스에 접근할 수 있는 '허용 가능한 Counter의 갯수'를 가지고 있는 Counter로 보면 된다. 예를 들면 107호 병실에 방문객용 의자가 5개 있다고 치자. 간호사는 이 병실에 방문자가 5명만 들어갈 수 있도록 허용하고 나머지 방문객들은 밖에서 대기하도록 한다. Counter 갯수만큼 공유자원(병실)에 접근할 수 있다.
세마포어는 Counter의 갯수에 따라 1개일 경우 이진 세마포어, 2개 이상일 경우 카운팅 세마포어라고 부른다. 이진 세마포어는 뮤텍스(MUTEX)라고도 한다.
*뮤텍스는 일종의 Locking 이다.
세마포어와 뮤텍스의 차이
공유 자원에 대한 접근권한, Lock 이라는 키를 한 개만 가지고 있는 것은 뮤텍스(MUTEX)이고 Lock 이라는 키를 여러 개 가질 수 있는 것은 세마포어(Semaphore)이다.
교착 상태(DeadLock)란 두 개 이상의 작업이 서로 상대방의 작업이 끝나기만을 기다리고 있는 상태이기 때문에 결과적으로 아무것도 완료되지 못하는 상태를 말한다.
다음과 같은 네 가지 조건을 모두 충족시킬 때 교착 상태가 발생할 수 있는데, 이 네 가지 조건중 하나라도 충족되지 않으면 교착 상태가 발생하지 않는다.
교착 상태 예방 기법은 교착 상태가 발생하지 않도록 사전에 시스템을 제어하는 방법으로 교착 상태 발생의 네 가지 조건 중에서 하나를 제거함으로써 수행된다.
교착 상태 회피 기법은 교착 상태가 발생할 가능성을 배제하지 않고 교착 상태가 발생하면 적절히 피해나가는 방법이다.
교착 상태 회피 기법은 덜 엄격한 조건을 요구하여 자원을 더 효율적으로 사용하는 것이 목적이다. 프로세스의 시작 중단과 자원 할당 거부(은행가 알고리즘) 등이 있다
교착 상태의 회복은 교착 상태를 일으킨 프로세스를 종료하거나 교착 상태의 프로세스에 할당된 자원을 선점하여 프로세스나 자원을 회복하느 것을 말한다.
교착 상태를 깨뜨리는 데는 두 가지 방법이 있다.
1. 순환 대기를 깨뜨리기 위해 한 개 이상의 프로세스를 중지 시키는 것
2. 교착 상태에 있는 하나 이상의 프로세스들러부터 자원을 선점하는 것
프로세스 종료
교착 상태에 있는 프로세스를 종료하는 것으로 교착 상태에 있는 모든 프로세스를 종료하는 방법과 프로세스들을 하나씩 종료해가며 교착 상태를 해결하는 방법이 있다.
자원선점
교착 상태의 프로세스가 점유하고 있는 자원을 선점하여 다른 프로세스에게 할당하며, 해당 프로세스를 일시 정지시키는 방법이다. 우선순위가 낮은, 수행된 정도가 적은, 사용되는 자원이 적은 프로세스 등을 위주로 해당 프로세스의 자원을 선점한다.
단일 프로그래밍 환경에서는 오로지 하나의 프로세스만이 메모리에 적재될 수 있었으므로 특별히 메모리 관리가 필요하지 않았다. 그러나 이후의 운영체제에서는 다중 프로그래밍 환경 즉 메모리에 여러 개의 프로세스가 동시에 적재되는 환경에서는 어느 프로세스를 어느 부분에 어떻게 적재할 것인가 하는 메모리 관리가 필요하게 되었다.
Swapping은 메모리에 적재되어 있으나 현재 사용되지 않고 있는 프로세스를 관리하는 역할을 한다. 메모리를 관리하기 위해 Swapping을 이용하면 현재 사용되지 않는 프로세스를 Backing store(하드 디스크)로 몰아낸다.(Swap-Out). 이와 반대로 필요한 부분이 생기면 그 부분에 대해 메모리로 적재해서 올려준다.(Swap-In)
각각의 프로세스가 메모리의 연속적인 공간에 적재하는 것이다.
다중 프로그래밍에서 연속 메모리 할당은 고정 분할과 가변 분할로 나눌 수 있다.
가변 분할에서 새로 들어오는 프로그램을 어느 빈 영역에 적재할 것인가를 결정하는 방법으로 3가지 방법이 존재한다.
페이징은 프로세스를 일정 크기인 페이지로 잘라서 메모리에 적재하는 방식이다. hole과 프로세스를 일정한 단위로 잘라서 사용하는 방식이다.
페이징 기법은 logical address 와 physical address 를 동일한 크기로 자르기 때문에 프로세스를 연속적으로 배치할 필요가 없다.(페이지 단위로 잘랐기 때문에) 따라서 외부 단편화가 발생하지 않는다는 장점이 있다.
내부 단편화는 발생할 수 있는데 페이지 크기를 줄이면 내부 단편화를 줄일 수 있다.
하지만 페이지 크기를 무작정 줄이면 페이지 수가 많아지고 페이지 테이블의 크기가 커져서 유지 비용이 많이 발생할 수 있다.
페이징은 프로세스를 물리적 단위인 페이지로 잘라서 적재하는 방법이었고 세그먼테이션은 프로세스를 물리적 단위가 아닌 논리적 단위인 세그먼트로 자르는 방법이다.
세그먼트들의 크기가 서로 다르기 때문에 메모리를 페이징 기법처럼 미리 분할해 둘 수 없고, 메모리에 적재될 때 빈 공간을 찾아 할당하는 사용자 관점의 가상메모리 관기 기법이다.
페이징과 마찬가지고 매핑을 위해 세그먼트 테이블이 필요하다.
내부 단편화는 발생하지 않으나 서로 다른 크기의 세그먼트들에 대해 필요시에 메모리에 올리고 필요 없을 경우 내리는 작업을 반복하다 보면 외부 단편화가 발생할 수 있다.