독립적인 프로세스끼리 작업을 하면 서로 데이터가 필요할 때가 있습니다. 데이터를 주고받을 때 통신을 사용하게 됩니다. 통신을 하면서, 누가 먼저 작업할 건지 언제 작업이 끝날지에 대해 서로 알려주는 것을 동기화라고 합니다. 같은 데이터를 여러 프로세스가 사용할 땐 서로 침범하면 안되는 임계구역도 필요합니다. 프로세스끼리 어떻게 통신을 하는지, 자원을 어떻게 나누며 동기화는 어떻게 하는 지 임계구역이 왜 필요한지를 이번 글에서 다뤄보도록 하겠습니다.
프로세스 통신
프로세스는 독립적으로 실행되기도 하지만 다른 프로세스와 데이터를 주고 받으며 협업을 하며 통신을 주고 받는 경우가 있습니다. 통신은 세 가지 방식으로 가능한데요, 프로세스 내부에서, 한 컴퓨터 내에서 실행되는 다른 프로세스와, 네트워크로 연결된 다른 컴퓨터에 있는 프로세스와도 함께 할 수 있습니다.
첫 번째로 다룰 것은 하나의 프로세스 내부에서 스레드끼리의 통신입니다. 쓰레드는 프로세스 내에서 코드, 데이터, 힙을 공유한다고 했죠. 이 공유하는 데이터의 전역변수나 파일, 힙을 통해 서로 통신하며 데이터를 주고받을 수 있습니다. 이때는 굳이 운영체제의 도움이 필요하지 않습니다. 그냥 데이터를 자기들끼리 갖다 쓰는 거니까요
두 번째는 프로세스 간 데이터 통신입니다. 프로세스 간 데이터 통신은 파일과 파이프를 이용합니다. 파일은 통신하려는 프로세스들이 하나의 파일을 이용해 읽고 쓰는 방법입니다. 파이프는 운영체제가 생성한 파이프를 이용해 데이터를 읽고 쓰는 방법입니다. 프로세스 내부에서는 운영체제가 개입하지 않지만 프로세스 간 데이터 통신에서는 파이프를 운영체제가 제공한다는 것을 알 수 있습니다.
마지막으로는 네트워크를 이용한 데이터 통신입니다. 여러 컴퓨터가 네트워크에 연결되어 있거나, 하나의 컴퓨터와 다른 컴퓨터의 데이터를 주고 받을 수 있는 통신입니다. 이 경우 프로세스는 운영체제가 제공하는 소켓을 이용해 데이터를 주고 받습니다. 소켓 통신으로 다른 컴퓨터의 함수를 호출하는 원격 프로시저 호출PRC도 포함하며, 소켓 통신을 네트워킹 통신이라고도 부릅니다.
이렇게 세가지의 방식으로 통신이 발생하곤 합니다. 여기서 전역 변수, 파일, 파이프, 소켓은 프로세스 간 통신의 매체입니다. 이 매체들의 특징과 이를 이용한 프로세스 동기화가 어떻게 이루어지는지 다뤄보겠습니다.
1. 전역변수
전역 변수는 같은 프로세스 안, 쓰레드에서 쓰입니다. 당연한 말이게도, 전역변수를 이용하면 공동으로 관리하는 메모리를 사용하여 데이터를 주고 받습니다.
데이터를 보내는 쪽에서 전역 변수에 값을 쓰고 데이터를 받는 쪽에서는 전역 변수의 값을 읽는 식입니다. 운영체제는 전역 변수에 개입하지 않습니다.
서로 연관이 없는 프로세스 간 통신에도 extern 변수와 같은 전역 변수를 사용할 수 있습니다.
2. 파일
파일은 말 그대로 저장장치에 파일을 읽고 쓰는 코드이며, 입출력을 하여 통신을 합니다. 파일 입출력 코드는 세 부분으로 나눠지는데, 열고open, 쓰거나 읽고 write read 연산 후, 파일을 닫는 close 것입니다. 파일 입출력 코드를 프로세스 입장에서 살펴보면, 쓰기를 요구하면 데이터가 저장되고, 읽기를 요구하면 입출력 관리 프로세스로부터 데이터를 가져옵니다. 이런 데이터 전송 명령, 데이터 가져오는 명령등이 운영체제에서도, 프로세스 입장에서도, 일반 프로세스와 입출력 프로세스 간의 통신입니다. 파일을 이용한 통신은 자주 사용되지만 운영체제가 프로세스 동기화를 제공하지는 않습니다. 프로세스 알아서 동기화를 하는데, 주로 wait()함수를 이용합니다.
3. 파이프
파이프는 운영체제가 제공하는 동기화 통신 방식입니다. 운영체제가 만든 파이프에 쓰기 연산, 읽기 연산을 통해 데이터 전송과 받아오는 것을 행합니다. 이또한 open(), close()함수를 이용합니다.
4. 소켓
여러 컴퓨터에 있는 프로세스 간 통신을 네트워킹이라고 부른다 하였습니다. 네트워킹 상황에서 통신은 원격 프로시저 호출이나 소켓을 이용합니다. 프로시저 호출은 한 컴퓨터 내에 있는 함수를 호출하는 것이고, 원격 프로시저 호출은 다른 컴퓨터의 함수를 호출하는 것입니다. 보통은 원격 프로시저 호출을 소켓을 이용합니다. 소켓을 이용하여 다른 컴퓨터에 있는 프로세스와 통신을 하려면, 컴퓨터의 위치를 파악하고 원격하려는 어떤 프로세스와 통신할 건지도 결정해야 합니다. 우리가 노트북과 패드로 크롬 페이지를 연결할 때, 괜히 패드의 위치를 묻는것을 생각하면 쉽습니다.
통신을 원하는 프로세스는 소켓에 쓰기 연산을 하여 데이터 전송을 하고 읽기 연산을 통해 데이터를 받습니다.
프로세스 간 데이터를 주고 받는 것을 통신이라고 하며, 이 행위는 읽기와 쓰기 연산으로 단순화 됩니다. 프로세스 특성에 따라 전역변수, 파일, 파이프, 소켓 등으로 통신을 할 수 있습니다.
프로세스 통신 방법 | 운영체제 동기화 | 통신 종류 |
전역변수 | X | 프로세스 내부(쓰레드) |
파일 | X (wait()함수) | 쓰레드, 프로세스 간 |
파이프 | O | 프로세스 간 |
소켓 | O | 네트워크 간 |
공유 자원과 임계구역
프로세스 간 통신을 할 때 공동으로 이용하는 변수, 메모리, 파일들을 공유 자원이라고 합니다. 공유 자원은 여러 프로세스가 공유하기 때문에 각 프로세스의 접근 순서에 따라, 프로세스 결과값이 달라질 수 있습니다. 그렇다고 어떤 프로세스가 먼저 실행되는 지 예측하기는 쉽지 않습니다. (Cpu스케줄링 처럼) 이 연산결과를 예측하기 힘들기 때문에 이 문제를 동기화 문제라고 부릅니다.
예시를 들어보겠습니다. 누구나 공동으로 이용하는 변수에 예금 10만원을 넣어보겠습니다. 앞으로 이 변수는 예금입니다. 그 후에, 프로세스1과 프로세스2가 이 예금에 접근한다고 생각해보겠습니다. 프로세스1은 예금 10만원을 확인하고 빠져있다가, 프로세스 2가 예금에 접근해 5만원을 넣습니다. 5만원을 저장하기도 전에 프로세스1이 예금에 10만원을 넣습니다. 그리고 프로세스2가 예금을 확인하면 20만원이 총 잔액으로 들어와 있습니다. 5만원은 어디간걸까요? 이미 5만원을 냈기 때문에 프로세스2에겐 5만원이 더 이상 존재하지 않지만, 총 예금에는 프로세스2가 낸 5만원이 있지 않습니다.
2개 이상의 프로세스가 공유 자원을 병행적으로 읽거나 쓰는 것을 '경쟁 조건'이 발생했다고 합니다. 이 경쟁 조건으로 인해 큰 문제가 더 일어나면서 혼란이 야기될 수 있겠죠. 이를 고치기 위해 프로세스가 동시에 사용하면 안되는 영역인 "임계구역"을 설정합니다.
이 임계구역에서는 프로세스들이 동시에 작업하면 안되며, 프로세스들은 임계구역에 들어간 프로세스를 대기큐에서 기다립니다.
한편, 임계구역이 명확하지 않으면 문제가 야기 됩니다. 하드웨어 측면에서 살펴보면, 프린터 1대를 두 컴퓨터가 나눠 쓰며 출력을 동시에 했다고 칩니다. 이 때, 명확하지 않은 임계구역으로 인해 두 개의 컴퓨터의 출력물이 뒤섞여 나올 수 있는 문제가 생깁니다.
임계구역을 어떻게 사용할 건지에 대한 해결방법으로, 여러 방안들이 나오곤 했습니다. 이 해결 방법을 알아보기 전에 알아야 할 세가지 조건이 있습니다. 이 조건들을 임계 구역 해결 조건이며, 이 세가지 조건을 만족해야만 임계구역의 문제를 해결하 수 있습니다.
1. 상호 배제
2. 한정 대기
3. 진행의 융통성
상호 배제 특성은 이 조건 중 제일 중요합니다. 한 프로세스가 임계구역에 들어가면 다른 프로세스는 임계구역에 들어갈 수 없는 특성입니다.꼭 임계구역 내에는 한 번에 하나의 프로세스만 있어야하는 원칙이 상호 배제입니다.
한정 대기 조건은 임계구역에 들어가지 못하여 기다리는 프로세스들이 무한 대기하지 않는 것입니다. 모든 프로세스들은 임계 구역에 진입할 수 있습니다.
진행의 융통성은 한 프로세스가 다른 프로세스의 진행을 방해해서는 안 되는 것을 의미합니다.
이 세가지가 지켜져야 임계구역 해결 방법이라고 할 수 있으며, 특히 상호 배제 특성이 제일 중요합니다.
임계구역 해결방안
임계구역의 문제 해결방안은 그냥 잠그는 것입니다. 임계구역을 잠금으로써, 상호 배제적 특성을 바로 지닐 수 있습니다. 하지만 냅다 잠금다고 모든 문제가 해결되는 것은 아니겠죠? 잠금과 관련하여 수많은 해결방안 알고리즘이 있었습니다.
세마포어
피터슨, 데커 알고리즘 등 임계구역의 문제를 해결하려는 시도는 많았습니다. 세마포어는 임계구역 문제를 해결할 수 있는 좋은 알고리즘입니다.
세마포어에서 프로세스는 공유자원을 쓰기 위해 대기큐에서 기다리며, 운영체제가 순서대로 공유자원을 임계구역에 들어가게 해줍니다. 세마포어는 세마포어를 선언하고, wait()함수를 사용해 임계구역을 잠금니다. 그리고 signal()함수가 호출될 때까지 기다립니다. 하지만 세마포어의 코드가 실행되는 도중에 다른 코드가 실행된다면? 상호 배제 원칙에서 어긋날 수 있습니다. 이처럼 세마포어를 이용하면 여러 프로세스가 동시에 접근하지는 못하지만, 함수의 이상한 사용으로 인해 임계구역이 제대로 보호받지 못합니다.
그렇다면 어떻게 임계구역도 보호받고, 해결방안의 조건을 만족할 수 있을까요?
바로 모니터입니다. 모니터는 진짜 우리가 아는 물리적 모니터가 아니라 코드, 알고리즘입니다.
모니터
모니터는 공유 자원을 내부적으로 숨기고 공유 자원에 접근하기 위한 인터페이스만 제공함으로써 자원을 보호하며 프로세스 간에 동기화를 시킵니다. 모니터는 시스템 콜의 개념과 같습니다. 시스템 콜은 운영체제가 자원을 숨기고 유저가 원하는 인터페이스만을 제공하는 것을 의미합니다. 시스템 콜처럼 모니터도 보호 자원을 임계구역에 숨기고 임계구역에서 작업할 수 있는 인터페이스만 제공하여 자원을 보호합니다.
즉, 임계구역에 들어가고자하는 프로세스는 모니터에 직접 작업요청을 하며, 모니터는 대기 해야할작업을 저장하고 순서대로 처리하여 결과만 프로세스에 알려주는 식입니다. 아예 접근을 못하게요! 이렇게 설정한다면 상호 배제원칙에도 어긋나지 않고, 무한 대기도 시키지 않으며, 서로 프로세스 간의 방해도 일어나지 않겠죠!
모니터의 구현이 완벽하다면, 프로그래머는 임계구역을 신경쓰지 않고 편리하고 안전하게 코드를 작성할 수 있습니다.
모니터의 하나 큰 특징이 있다면, 프로그래밍 언어차에서 지원한다는 것입니다. 대표적으로 자바에서 이를 지원하는데, 자바에서 Syncronized가 붙는다면 그 구역은 임계지역으로 건들이면 안되는 곳입니다.
이번 포스팅에서는 프로세스 간 데이터를 주고 받는 것을 어떻게 하는 지(통신), 통신 종류는 무엇이 있는지(전역변수, 파일, 파이프, 소켓),
통신을 통한 데이터 접근을 하면서 어떤 과정을 겪는 지, 그 과정에서 공유 자원을 어떻게 활용하는 지, 공유 자원을 쓰면서 문제점인 임계구역의 문제와 해결 조건, 해결 방법을 알아보았습니다.
'CS' 카테고리의 다른 글
OS | 메모리 (0) | 2025.03.26 |
---|---|
OS | 교착상태, 데드락 (5) | 2025.03.26 |
OS | CPU 스케줄러, CPU 스케줄링 알고리즘 (0) | 2025.03.26 |
OS | 프로세스와 스레드 (0) | 2025.03.26 |
OS | 운영체제 컴퓨터의 구조, 특성 (0) | 2025.03.26 |