tlov

[스터디] 5-1. 동기화란? 본문

개발/운영체제

[스터디] 5-1. 동기화란?

nowitzki 2024. 8. 15. 16:26

동시다발적으로 실행되는 프로세스 또는 스레드들은 서로 협력하며 영향을 주고 받는다.

이 과정에서 자원의 일관성을 보장해야 한다.

 

아래에서는 프로세스 단어만 언급하지만, 실제로는 스레드에도 적용되는 내용이다.

 

동기화의 의미

공동의 목적을 이루기 위해서 동시에 협력하며 수행되는 프로세스들이 있다. 가령 워드 프로세서 프로그램이 있다면 맞춤법을 검사해주는 프로세스, 화면에 출력해주는 프로세스 등이 포함될 수 있다. 하지만 이러한 프로세스들이 마구잡이 수행되어도 괜찮을까?

 

아니다. 올바른 수행을 위해서는 프로세스들이 동기화 되어야 한다. 왜냐면, 자원의 일관성을 보장해야 하기 때문이다.

 

동기화란 프로세스들의 수행 시기를 맞추는 것이다. 크게 두 가지로 나뉜다.

1. 실행 순서 제어 : 프로세스를 올바른 순서대로 실행하기

2. 상호 배제 : 동시에 접근하면 안되는 자원에 하나의 프로세스만 접근하도록 하기

 

 

 

1. 실행 순서 제어 동기화

 

reader writer problem

writer: Book.txt 파일에 값을 저장하는 프로세스

reader: Book.txt 파일에 저장된 값을 읽어들이는 프로세스

 

이 두 개의 프로세스가 동시에 실행된다고 가정해보자. 무작정 동시에 실행해도 괜찮을까? No

실행의 순서가 있다. reader 프로세스는 Book.txt 안에 값이 존재한다는 특정 조건이 만족해야만 실행할 수 있기 때문이다. 즉, writer의 실행이 선행되어야 한다. 이러한 문제를 해결하는 것이 실행 순서 제어 동기화이다.

 

 

 

2. 상호 배제 동기화

해당 동기화는 공유가 불가능한 자원의 동시 사용을 피하기 위한 동기화이다. 프린터와 같이 반드시 한 번에 하나의 프로세스만 이용 가능한 자원이 있다면 이를 한 번에 하나의 프로세스만 이용 가능하도록 하는 것이 상호 배제를 위한 동기화이다.

 

Bank account problem

현재 계좌에 잔액: 10만원

프로세스 A는 현재 잔액을 읽어 2만원을 추가하는 프로세스

프로세스 B는 현재 잔액을 읽어 5만원을 추가하는 프로세스

 

두 프로세스를 무작정 동시에 실행했다고 가정해보자. 그럼 예상대로 17만원이 남아있을까? No

동기화가 제대로 이루어지지 않은 경우 다른 값이 저장될 수 있다. 예를 들어 프로세스 A가 실행되면서 잔액을 읽고, 해당 잔액 10만원에 2만원을 더하고 값을 계좌에 저장하기 전 문맥 교환이 일어나 프로세스 B가 실행된다면, B에서 읽어들인 잔액은 10만원이기 때문에 값을 저장 시 17만원이 아닌 15만원 혹은 12만원이 저장될 수 있다.

 

이러한 문제가 발생한 이유는 공유되는 자원에 두 프로세스가 동시에 접근하였기 때문이다. 그렇다면, 이 문제를 해결하기 위해서는 어떤 프로세스가 자원을 읽고 있는 상태였다면 문맥 교환이 되더라도 다른 프로세스가 자원에 접근하지 못하도록 하면 된다. 이를 상호 배제 동기화라고 한다.

 

Producer & Cunsumer problem

생산자, 물건을 계속해서 생산하는 프로세스

소비자, 물건을 계속해서 소비하는 프로세스

'총합' 변수를 공유한다.

 

생산자

생산자 () {
	버퍼에 데이터 삽입
    '총합' 변수 1 증가
}

 

소비자

소비자 () {
	버퍼에서 데이터 빼내기
    '총합' 변수 1 감소
}

 

총합이라는 변수는 생산자와 소비자 모두 공유하는 변수이고 초기값은 10이라고 해보자.

이러한 상태에서 생산자를 10만번, 소비자를 10만번 실행하면 총합이 10이 될까? No

 

실제로 코드를 작성해 실행해보면 총합의 값이 계속 다르게 출력되는 것을 확인할 수 있다. 이는 상호 배제 동기화가 되지 않았기 때문에 발생하는 문제이다.

 

그럼, 동시에 접근하면 안되는 자원은 뭘까?

 

공유 자원: 여러 프로세스 혹은 스레드가 공유하는 자원 (ex. 전역 변수, 파일, 입출력 장치, 보조기억장치, ...)

임계 구역: 동시에 실행하면 문제가 발생하는 자원에 접근하는 코드 영역

 

임계 구역에 진입하고자 하면 진입한 프로세스 이외에는 대기해야 한다. 임계 구역에 동시에 접근하면 자원의 일관성이 깨질 수 있는데 이를 '레이스 컨디션(race condition)'이라고 한다. 이러한 레이스 컨디션이 발생하는 이유가 무엇인가 좀 더 살펴보면 다음과 같다.

 

총합을 더하는 코드는 실제로 한 줄로 작성이 되지만, 이것을 컴파일하고 저급언어로 변환되면 사실 한 줄이 아니다.

r1 = 총합;
r1 = r1 + 1;
총합 = r1;

 

이처럼 레지스터에 값을 저장하고 증가시킨 후에 총합을 갱신한다. 그래서 CPU가 총합에 레지스터 값을 저장하기 전에 문맥교환이 일어나 이러한 레이스 컨디션 문제가 발생하는 것이다.

 

 

운영체제가 임계 구역 문제를 해결하는 세 가지 원칙(=상호 배제 동기화를 위한 세 가지 원칙)

1. 상호 배제 (mutual exclusion) : 한 프로세스가 임계 구역에 진입했다면 다른 프로세스는 들어올 수 없다.

2. 진행 (progress) : 임계 구역에 아무도 없다면, 진입하고자 하는 프로세스는 들어갈 수 있어야 한다.

3. 유한 대기 (bounded waiting) : 한 프로세스가 임계 구역에 진입하고 싶다면 언젠가는 임계 구역에 들어갈 수 있어야 한다. (무한정 대기해서는 안된다.)

 

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

02-1. 시스템 구조와 프로그램 실행  (0) 2024.08.16
01. 운영체제 개요  (0) 2024.08.16
[스터디] 4-2. CPU 스케줄링 알고리즘  (1) 2024.08.15
[스터디] 4-1. CPU 스케줄링  (0) 2024.08.15
[스터디] 3-3. 스레드  (0) 2024.08.15