본문 바로가기
시리즈/운영체제

[운영체제] 프로세스 동기화

by 되고싶은노력가 2025. 2. 10.

동기화란

운영체제의 프로세스 관리 서비스 중 가장 중요한 두 가지를 꼽자면 스케줄링과 동기화입니다. 동시다발적으로 실행되는 프로세스들은 공동의 목적을 올바르게 수행하기 위해 서로 협력하며 영향을 주고 받기도 합니다. 이렇게 협력하여 실행되는 프로세스들은 실행 순서와 자원의 일관성을 보장해야 하기에 반드시 동기화되어야 합니다.

 

동기화의 의미

프로세스 동기화란 '작업들 사이의 수행 시기를 맞추는 것'을 의미합니다. 다시 말해 프로세스 동기화프로세스들 사이의 수행 시기를 맞추는 것을 의미합니다. 수행 시기를 맞춘다는 것은 크게 아래 두 가지를 일컫습니다.

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

 

실행 순서 제어

'쓰기'와 '읽기'라는 프로세스가 동시에 실행 중이라고 가정해보겠습니다. 만약 '쓰기' 프로세스가 값을 저장하기도 전에 '읽기' 프로세스가 동작한다면 이는 올바른 실행 순서가 아니게 됩니다. 이를 올바르게 실행하려면 '쓰기'가 완료되고 난 후 값이 존재할 때 '읽기' 프로세스가 동작해야겠지요. 이를 실행 순서 제어에 대한 프로세스 동기화라고 할 수 있습니다.

상호 배제

상호 배제공유가 불가능한 자원의 동시 사용을 피하기 위해 사용하는 알고리즘입니다. 가령 계좌에 10만원이 저축되어 있다고 가정해 보겠습니다. 그리고 2만 원을 넣는 프로세스 A,  5만 원을 넣는 프로세스 B가 있다고 했을 때 동시에 실행한다면 어떻게 될까요? 

 

실행 결과가 17만 원이라 기대하겠지만 동기화가 제대로 이루어지지 않은 경우 위와 같이 전혀 엉뚱한 결과가 나올 수 있습니다. 이렇게 되는 이유는 프로세스 A가 끝나기 결과를 저장하기 전에 프로세스 B가 이전의 잔액을 읽어 버렸기 때문입니다.

 

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


공유 자원과 임계 구역

그렇다면 동시에 접근해서는 안 되는 자원이란 무엇일까요? 앞선 예시에서 우리는 전역 변수 '잔액'이라는 공동의 자원을 두고 작업을 했습니다. 이러한 자원을 공유 자원이라고 합니다. 그리고 공유 자원 중에 동시에 실행하면 문제가 발생하는 자원에 접근하는 코드 영역임계 구역이라고 합니다.

 

두 개 이상의 프로세스가 임계 구역에 진입하고자 하면 둘 중 하나는 대기해야합니다. 만약 잘못된 실행으로 인해 여러 프로세스가 임계 구역의 코드를 실행하여 문제가 발생한다면 이를 레이스 컨디션이라고 합니다.

 

운영체제는 이러한 임계 구역 문제를 아래 세 가지 원칙 하에 해결합니다. 달리 말해 상호 배제를 위한 동기화를 위해서는 아래 세 가지 원칙이 반드시 지켜져야만 합니다.

  • 상호 배제 : 한 프로세스가 임계 구역에 진입했다면 다른 프로세스는 임계 구역에 들어올 수 없다.
  • 진행 : 임계 구역에 어떤 프로세스도 진입하지 않았다면 임계 구역에 진입하고자 하는 프로세스는 들어갈 수 있어야 한다.
  • 유한 대기 :한 프로세스가 임계 구역에 진입하고 싶다면 그 프로세스는 언젠가는 임계 구역에 들어올 수 있어야 한다.

동기화 기법

어떻게 해야 임계 구역에 오직 하나의 프로세스만 진입하게 하고, 올바른 실행 순서를 보장 할 수 있을까요? 이를 위해 프로세스 동기화를 구현한 대표적인 도구 뮤텍스 락, 세마포, 모니터를 알아 보겠습니다.

 

뮤텍스 락

임계 구역에 진입하는 프로세스는 임계 구역에 있음을 알리기 위해 자물쇠를 걸어둘 수 있고, 다른 프로세스는 잠겨 있다면 기다리고, 잠겨 있지 않다면 임계 구역에 진입할 수 있습니다.

 

뮤텍스 락의 매우 단순한 형태는 하나의 전역 변수 lock과 임계 구역을 잠그는 역할 acquire 함수, 임계 구역의 잠금을 해제하는 역할 release 함수로 구현할 수 있습니다.

 

특징으로 하나의 공유 자원에 접근하는 프로세스를 상정한 방식이라는 점과 임계 구역이 잠겨 있는지 열려있는지 계속해서 확인을 해야하는 바쁜 대기 방식을 가진다는 점입니다.


세마포

세마포는 뮤텍스 락과 비슷하지만, 조금 더 일반화된 방식의 동기화 도구입니다. 뮤텍스 락에서는 탈의실이 하나였다면 세마포는 탈의실이 여러 개 있는(공유 자연이 여러 개 있는), 임계 구역에 여러 개의 프로세스가 접근할 수 있도록 하는 방식입니다.

 

세마포도 뮤텍스와 비슷하게 임계 구역에 진입할 수 있는 프로세스의 개수를 나타내는 전역 변수 S임계 구역에 들어가도 좋은지, 기다려야 할지를 알려주는 wait 함수, 임계 구역 앞에서 기다리는 프로세스에 '이제 가도 좋다'고 신호를 주는 signal 함수가 있습니다.

 

실제로는 바쁜 대기 문제를 해결하기 위해 wait 함수는 사용할 수 있는 자원이 없을 경우 프로세스 상태를 대기 상태로 만들고 대기 큐에 넣습니다. 그리고 다른 프로세스가 끝나고 signal 함수가 호출되면 대기 중인 프로세스를 대기 큐에서 제거하고 준비 상태로 변경한 뒤 준비 큐로 옮겨 줍니다.


모니터

세마포 자체로도 훌륭한 프로세스 동기화 도구이지만, 코드가 방대해지고 복잡해지면 함수를 명시하는 코드에서 잘못 사용할 수 있습니다. 이에 최근에 등장한 도구가 모니터입니다.

 

모니터는 공유 자원과 공유 자원에 접근하기 위한 인터페이스를 묶어 관리합니다. 그리고 프로세스는 반드시 인터페이스를 통해서만 공유 자원에 접근하도록 합니다. 즉, 모니터는 공유 자원을 다루는 인터페이스에 접근하기 위한 큐를 만들고, 모니터 안에 항상 하나의 프로세스만 들어오도록 동기화를 제공합니다.

 

이 밖에도 모니터는 실행 순서 제어를 위한 동기화도 제공합니다. 프로세스를 실행하고 일시 중단하기 위해 모니터는 조건 변수를 사용하는데 이는 프로세스나 실행 순서를 제어하기 위해 사용하는 특별한 변수입니다.

 

조건 변수로는 waitsignal 연산을 수행할 수 있습니다. wait 연산은 어떤 프로세스를 대기 상태로 변경하고 조건 변수에 대한 큐에 삽입하는데 앞에서 말한 큐는 한 번에 하나의 프로세스만 진입하도록 하기 위해 만들어진 큐이고, 지금 말하는 큐는 실행 조건이 만족될 때까지 잠시 실행이 중단되어 기다리기 위해 만들어진 큐입니다.

 

signal 연산은 wait 연산으로 일시 중지된 프로세스를 재개시키는 연산입니다. 즉, signal은 wait을 호출하여 큐에 삽입된 프로세스의 실행을 재개하는 연산입니다.