개발자는 기록이 답이다

혼공 컴퓨터구조 + 운영체제 12. 프로세스 동기화 본문

CS/운영체제

혼공 컴퓨터구조 + 운영체제 12. 프로세스 동기화

slow-walker 2024. 2. 4. 22:22

1. 동기화란?

 

프로세스들을 무작정 동시에 실행해도 괜찮을까?


동시다발적으로 실행되는 프로세스들은 공동의 목적을 올바르게 수행하기 위해 서로 협력하며 영향을 주고 받는다.

이렇게 협력하여 실행되는 프로세스들은 실행 순서와 자원의 일관성을 보장 해야 하기에 반드시 동기화 synchronization 되어야 한다.

 

동기화의 의미


동시다발적으로 실행되는 많은 프로세스는 서로 데이터를 주고받으며 협력하며 실행될 수 있다.

  • 워드 프로세서에는 사용자로부터 입력을 받는 프로세스
  • 입력한 내용의 맞춤법 검사하 는 프로세스 입력한 내용을 화면에 출력해 주는 프로세스

이 프로세스들은 각기 다른 독립적인 프로세스이지만 공동의 목표를 위해 서로 협력하는 존재다.


이렇게 협력적으로 실행되는 프로세스들은 아무렇게나 마구 동시에 실행해서는 안된다. 올바른 실행을 위해서는 동기화가 필수다.

 

프로세스 동기화란 무엇일까? 

 

국어 사전에 따르면 '정보통신 분야에서 작업의 수행 시기를 맞추는 것'을 의미한다고 나와 있다.

다시 말해, 프로세스 동기화 프로세스를 사 이의 수행 시기를 맞추는 것을 의미한다.

 

프로세스들 사이의 수행 시기를 맞추는 것은 무엇을 의미 할까? 

  • 실행 순서 제어: 프로세스를 올바른 순서대로 실행하기
  • 상호 배제: 동시에 접근해서는 안 되는 자원에 하나의 프로세스만 접근하게 하기

※ 프로세스뿐만 아니라 스레드도 동기화 대상이다. 정확히 말하면 실행의 흐름을 갖는 모든 것은 동기화의 대상이다.

 

 

첫째, 실행 순서 제어를 위한 동기화


가령 Writer라는 프로세스와 Reader라는 프로세스가 동시에 실행 중이라고 가정해자. 

  • Writer 프로세스는 Book.txt 파일에 값을 저장하는 프로세스이고,
  • Reader 프로세스는 Book.txt 파일에 저장된 값을 읽어 들이는 프로세스다.

 

이 두 프로세스는 무작정 아무 순서대로 실행되어서는 안 된다. 

 

Reader 프로세스는 Writer 프로 세스 실행이 끝나야 비로소 실행할 수 있기 때문이다. 

Writer 프로세스가 Book.txt에 값을 저장하기도 전에 Reader 프로세스가 Book.txt를 읽는 것은 올바른 실행 순서가 아니다. 

 

다시 말해 Reader 프로세스는 'Book.txt 안에 값이 존재한다'는 특정 조건이 만족되어야만 실행을 이어나갈 수 있다.

이렇게 동시에 실행되는 프로세스를 올바른 순서대로 실행하는 것이 실행 순서 제어를 위한 동기화이다.


둘째, 상호 배제를 위한 동기화


상호 배제(mutual exclusion)공유가 불가능한 자원의 동시 사용을 피하기 위해 사용하는 알고리즘이다.

 

가령 계좌에 10만 원이 저축되어 있다고 가정해보자.

  • 프로세스 A는 현재 저축된 금액에 2만 원을 넣는 프로세스
  • 프로세스 B는 현재 저축된 금 액에 5만 원을 넣는 프로세스


▶ 프로세스 A가 실행되는 과정

 

① 계좌의 잔액을 읽어 들인다.
② 읽어 들인 잔액에 2만 원을 더한다.
③ 더한 값을 저장한다.

  프로세스 B가 실행되는 과정


① 계좌의 잔액을 읽어 들인다.
② 읽어 들인 잔액에 5만 원을 더한다.
③ 더한 값을 저장한다.

 

이제 프로세스 A와 B가 동시에 실행되었다고 가정해 보자. 당연히 실행 결과 17만 원이 계좌에 남을 것을 기대할 것이다.

하지만 동기화가 제대로 이루어지지 않은 경우 아래 왼쪽 사진과 같이 전혀 엉뚱한 결과가 나올 수 있다.

 

A와 B는 '잔액'이라는 데이터를 동시에 사용하는데, A가 끝나기도 전에 B가 잔액을 읽어버렸기 때문에 엉뚱한 결과가 나온 것이다.

A와 B를 올바르게 처리하기 위해서는 한 프로세스가 잔액에 접근했을때 다른 프로세스는 기다려야 한다.

 

이렇게 동시에 접근해서는 안되는 자원에 동시에 접근하지 못하게 하는것이 상호 배제를 위한 동기화 이다.

 

2. 동기화 기법

 

뮤텍스 


옷가게에서 마음에 드는 옷이 있으면 손님은 탈의실에 들어가서 옷을 입어볼 수 있다.

탈의실에는 한 명의 인원만 들어갈 수 있다.

  • 손님 : 프로세스
  • 탈의실(자원) : 임계 구역


만일 밖에서 탈의실에 사람이 있는지 없는지 알 수 없는 상황이라면 어떻게 탈의실이 이용 중임을 알 수 있을까? 

 

일단 탈의실을 열어 보고 자물쇠가 걸려 있다면 탈의실 안에 사람이 있다고 판단하고 기다린다. 

자물쇠가 걸려 있지 않다면 탈의실을 이용하면 된다.


이 자물쇠 기능을 코드로 구현한 것이 뮤텍스 락 (Mutex lock; Mutual Exclusion iock)이다.

 

  • 뮤텍스 락 : 동시에 접근해서는 안 되는 자원에 동시에 접근하지 않도록 만드는 도구(상호 배제를 위한 동기화 도구)

 

임계 구역에 진입하는 프로세스는 '내가 지금 임계 구역에 있음'을 알리기 위해 뮤텍스 락을 사용해 임계 구역에 자물쇠를 걸어둘 수 있고,

다른 프로세스는 임계 구역이 잠겨 있다면 기다리고, 잠겨 있지 않다면 임계 구역에 진입할 수 있다.


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


• 자물쇠 역할: 프로세스들이 공유하는 전역 변수 lock
• 임계 구역을 잠그는 역할: acquire 함수
• 임계 구역의 잠금을 해제하는 역할: release 함수

 

  • acquire 함수 : 프로세스가 임계 구역에 진입하기 전에 호출하는 함수
    • 만일 임계 구역이 잠 겨 있다면 임계 구역이 열릴 때까지(lock이 false가 될 때까지) 임계 구역을 반복적으로 확인하고,
    • 임계 구역이 열려 있다면 임계 구역을 잠그는(lock을 true로 바꾸는) 함수
  • release함수 : 임계 구역에서의 작어이 끝나고 호출하는 함수
    • 현재 잠긴 임계 구역을 열어주는(lock을 false로 바꾸는) 함수
세마포

 

세마포(semaphore)는 뮤텍스 락과 비슷하지만, 조금 더 일반화된 방식의 동기화 도구이다.

 

  • 뮤텍스락 : 하나의 공유 자원에 접근하는 프로세스를 상정한 방식
    • 즉, 탈의실이 하나 있는 경우를 가정 하고 만든 동기화 도구
  • 세마포 : 공유 자원이 여러 개가 있는 경우, 여러 개의 프로세스가 각각의 공유 자원에 접근 가능한 방식
    • 즉, 탈의실이 여러 개 있는 상황처럼 공유 자원이 여러 개 있을 경우 (각 공유 자원에는 하나의 프로세스만 진입이 가능할지라도) 


▶ 옷가게에 탈의실이 세 개 있다고 생각해보자.

 

여전히 하나의 탈의실에는 한 사람만 들어 갈 수 있지만 이 경우에는 세 명이 동시에 탈의실을 이용할 수 있다. 

 

 한 번에 하나의 프로세스만 이용할 수 있는 프린터 세 대가 있다고 해보자.

 

하나의 프린터를 사용할 수 있는 프로세스는 하나이지만, 총 세 개의 프로세스가 공유 자원(세대의 프린터)를 이용할 수 있다.

 

 

※ 엄밀히 말하면 세마포의 종류에도 이진 세마포(binary semaphore)카운팅 세마포(counting semaphore)가 있지만, 이진 세마포는 뮤텍스 락과 비슷한 개념이다.

 

모니터

 

세마포는 그 자체로 매우 훌륭한 프로세스 동기화 도구이지만, 사용하기가 조금 불편하다. 

매번 임계 구역에 앞뒤로 일일이 wait와 signal 함수를 명시하는 것은 번거로운 일이기 때문이다.

더군다나 자칫 아래처럼 잘못된 코드로 인해 예기치 못한 결과를 얻을 수도 있다. 코드가 방대해지고 복잡해지면 아래와 같은 상황은 얼마든지 발생할 수 있다.

 

이에 최근에 등장한 동기화 도구가 모니터(monitor)이다.

 

  • 모니터 : 세마포에 비하면 사용자가 사용하 기에 훨씬 편리한 도구로서 조건 변수를 사용한다
    • 모니터는 공유 자원과 공유자원에 접근하기 위한 인터페이스(통로)를 묶어 관리한다.
    • 그리고 프로세스는 반드시 인터페이스를 통해서만 공유 자원에 접근하도록 한다.