동기화는 무엇일까?
프로세스 동기화 (Process Synchronization)
--
운영체제에서 여러 프로세스가 공유 자원을 함께 사용할 때,
경쟁을 방지하고 일관성을 유지하며 공유하기 위한 메커니즘이다.
즉, 프로세스들 사이의 수행 시기를 맞추는 것을 의미한다.
- 실행 순서 제어 : 프로세스를 올바른 순서대로 실행한다.
- 상호 배제 : 동시에 접근하면 안 되는 자원에 하나의 프로세스만 접근하도록 한다.
프로세스뿐만 아니라 스레드도 동기화 대상이다.
정확히는 실행의 흐름을 갖는 모든 것이 동기화의 대상이다.
실행 순서 제어를 위한 동기화
프로세스 A와 프로세스 B가 존재한다고 가정하자.
- 프로세스 A : test.txt파일에 값을 저장하는 프로세스
- 프로세스 B : test.txt파일에 값을 읽는 프로세스
프로세스 A, B는 무작정 아무 순서로 실행되어서는 안 된다.
파일을 읽어오는 프로세스 B를 test.txt파일에 값을 저장하기도 전에 읽는 것은 올바른 순서가 아니기 때문이다.
즉, test.txt파일에 값이 존재한다는 조건이 만족되어야 프로세스 B를 실행할 수 있다.
이것이 실행 순서 제어를 위한 동기화다.
상호 배제를 위한 동기화
만약 내 계좌에 100만 원이 저축되어 있다고 가정하자.
- 프로세스 A : 내 저축된 돈에 + 50만 원 값을 저장 (50만 원 저축)
- 프로세스 B : 내 저축된 돈에 + 10만 원 값을 저장 (10만 원 저축)
상호 배제를 위한 동기화를 하지 않았을 경우
잔액이라는 자원에 두 개 이상의 프로세스가 접근하여 자원을 신경 쓰지 않고 자기 할 일만 동작한 결과로
예상한 결과와 다르게 나온다.
위 그림처럼 상호 배제를 위한 동기화를 하면
프로세스 A의 작업이 모두 끝나고 나서 프로세스 B의 작업이 동작하니
동시에 공유 자원을 사용하는 일이 없으며,
이로 인해 서로 충돌하지 않고 예산한 결과가 나오는 것을 확인할 수 있다.
공유 자원과 임계 구역
위 설명처럼
여러 프로세스가 하나의 자원을 같이 사용하는 것을 "공유 자원"이라고 하며,
이렇게 동시에 실행하면 문제가 발생하는 "공유 자원"에 접근하는 코드 영역을 "임계 구역"이라고 부른다.
즉, 상호 배제를 위한 동기화를 하기 위해서는
두 개 이상의 프로세스가 "임계 구역"에 진입하고자 하면 하나의 프로세스를 제외한 나머지는 대기해야 한다.
그리고 먼저 진입한 프로세스의 작업이 마무리되면 그제야 대기하고 있던 프로세스가 임계 구역에 진입하게 된다.
레이스 컨디션 (Race Condition)은
두 개 이상의 프로세스가 동시에 실행되면 안 되는 "임계 구역"에
잘못된 실행으로 인해 여러 프로세스가 동시 다발적으로 실행되어 문제가 발생되는 현상을 의미한다.
레이스 컨디션이 발생하는 근본적인 이유
일반적으로 코드는 고급 언어를 통해 간단하게 작성할 수 있지만
컴퓨터 내부에서는 해당 고급 언어를 해석하여 저급 언어로 변환하여 사용하게 된다.
고급 언어를 저급 언어로 변환하면 코드의 수가 길어진다.
즉, 고급 언어의 한 줄 코드가 저급 언어로 변환될 때 해당 코드가 여러 단계의 작업으로 분할되어 실행되고
이 과정에서 문맥 교환이 발생할 때 해당 문제가 발생될 수 있다.
--
동기화 기법
--
대표적인 동기화 기법(도구)들
- 뮤텍스 락 (Mutex Lock)
- 세마포어 (Semaphore)
- 모니터 (Monitor)
뮤텍스 락 (Mutex Lock)
상호 배제를 보장하는 기본적인 동기화 기법으로
임계 구역에 들어가려는 프로세스가 직접 이진 락(Binary Lock)이라는 자물쇠를 가지고 자원에 대해 락을 걸어
자원을 보호하는 임계 구역에 접근하지 못하도록 한다.
비유를 하자면 공공시설에 배치된 화장실과 비슷하다.
내가 화장실에 들어가서 잠금을 하면 외부에서는 해당 화장실 칸은 사용 중이라고 표시되며 접근할 수 없게 된다.
그리고 내가 나갈 때에는 잠금을 풀고 나가게 되며, 이때 잠금이 풀렸으니 다음 사람이 들어가서 또 잠금을 건다.
세마포어 (Semaphore)
뮤텍스 락과 비슷한 동기화 기법이지만 조금 더 일반화된 방식의 동기화 기법으로
뮤텍스 락은 하나의 공유 자원에 접근하는 프로세스를 상정하는 방식이고 (공유 자원(화장실 칸)이 하나뿐)
세마포어는 공유 자원이 여러 개 있는 경우 여러 개의 프로세스가 각각 공유 자원에 접근이 가능하도록 하는 방식이다.
(각 공유 자원에 하나의 프로세스만 접근 가능한 것은 동일하다.)
여기서 세마포어는
정수 값을 사용하여 여러 프로세스가 공유 자원에 접근할 수 있는 동시 접근 수를 제어하는 동기화 기법이다.
즉, 정수 값을 이용해서 여러 공유 자원에 프로세스들이 접근하는 것을 관리하는 것이다.
다시 정리하자면
정수의 값을 사용하여 여러 프로세스 또는 스레드가 동시에 공유 자원에 접근할 수 있는 수를 제어하는 동기화 기법으로, 세마포어는 자원의 수를 제한하고, 몇 개의 프로세스가 동시에 자원에 자원에 접근할 수 있는지를 관리하는 데 사용한다.
정수의 값은 허용 가능한 자원의 최대 수를 나타낸다.
만약 정수 값(자원 수)이 N = 3일 때
프로세스 A가 자원에 접근할 때 해당 정수 값(N)을 확인 후 0이 아니라면 접근이 가능하다고 판단 후 접근한다.
이때 접근하게 되면 정수 값(N)을 -1 하여 3개 중 하나는 사용 중이라는 것을 표시한다.
쭉 진행하다가 정수 값(N)이 0이 되면 더 이상 사용할 수 있는 자원이 없다는 의미로 프로세스는 대기하게 된다.
P 연산은
프로세스가 자원을 사용할 때 자원의 개수에서 -1 연산을 하는 것을 의미하고
V 연산은
자원을 사용한 뒤에 빠져나올 때 +1 연산을 하여 다시 반납하는 것을 의미한다.
세마포어의 종류
- 이진 세마포어 (Binary Semaphore) : 0 또는 1을 가질 수 있으며, 뮤텍스와 유사하게 동작 (0 = 잠금, 1 = 해제)
- 카운팅 세마포어 (Counting Semaphore) : 0 이상의 값을 가질 수 있으며, 자원의 개수를 제한
이진 세마포어는 뮤텍스 락과 비슷하게 0과 1로만 해당 자원을 사용 중인지 아닌지를 판별하는 것이고
카운팅 세마포어는 위에서 설명한 것처럼 사용중인 자원을 카운팅 하여 접근 가능한지 판별하는 것이다.
모니터 (Monitor)
세마포어는 아주 좋은 프로세스 동기화 기법이지만
매번 정수에 +1, -1을 해주면서 사용하기가 조금 불편한 면이 존재한다.
자칫 잘못하면 예기치 못한 결과를 얻을 수도 있기 때문이다.
모니터는
최근에 등장한 동기화 기법으로
객체나 클래스 단위에서 동기화를 관리한다.
내부적으로 "조건 변수(Condition Variable)"를 사용하여 특정 조건이 충족되었을 때 대기 중인 프로세스를 실행한다.
위 그림처럼
공유 자원과 공유 자원에 접근하기 위한 인터페이스(통로)를 묶어 관리한다.
프로세스는 반드시 인터페이스(통로)를 통해서만 공유 자원에 접근할 수 있으며
큐에 삽인 된 순서대로 하나씩 공유 자원을 이용하도록 한다.
즉, 모니터는 공유 자원을 다루는 인터페이스(통로)에 접근하기 위한 큐(모니터에 접근하기 위한 큐)를 따로 만들고,
모니터 안에 항상 하나의 프로세스만 들어오도록 하여 상호 배제를 위한 동기화를 제공한다.
그리고 특정 조건을 바탕으로 프로세스를 실행하고 일시 중단하기 위해 "조건 변수(Condition Variable)"를 사용하여,
프로세스나 스레드의 실행 순서를 제어하는 동기화도 제공한다.
--
'CS > 운영체제' 카테고리의 다른 글
[메모리 관리] 연속 메모리 할당 (+ 스와핑, 외부 단편화) (0) | 2024.10.01 |
---|---|
교착 상태 (0) | 2024.09.30 |
CPU 스케줄링 알고리즘 종류 (1) | 2024.09.28 |
CPU 스케줄링 (0) | 2024.09.26 |
스레드 (+ 멀티프로세스와 멀티스레드) (1) | 2024.09.25 |