안녕하세요.
지난번 포스팅에서 병행프로세스 상황에서의 프로세스의 관계에 대하여 알아보았습니다.
병행프로세스에는 독립프로세스와 협력프로세스가 존재한다고 말씀드렸었습니다.
오늘은 그중 하나인 협력 프로세스에 대해서 더 자세하게 알아보려고 합니다.
협력프로세스
지난 포스팅에서 협력프로세스란 수행 중인 다른 프로세스와 영향을 주고받으며 데이터 및 상태를 공유하는 프로세스라고 말씀드렸습니다.
협력 프로세스의 실행은 비결정적, 재생불가능 하다는 특징을 가지고 있고 실행 결과가 실행 순서에 따라 좌우되며 같은 입력에 대해 항상 동일한 결과를 보장하지 못한다는 특징을 가집니다.
이러한 협력 프로세스 사이에는 다양한 문제가 발생할 수 있는데요.
어떤 문제들이 발생할 수 있는지 알아보며 협력프로세스의 일반적 구현방법에 대해서 알아보겠습니다.
협력프로세스에서 발생 가능 문제
- 생산자-소비자 문제
- 판독기-기록기 문제
- 통신문제
협력프로세스에서 발생 가능한 문제는 위와 같은 크게 세 가지 문제로 나눌 수 있습니다.
그럼 각 문제에 대하여 조금 더 자세하게 알아보겠습니다.
생산자-소비자 문제
생산자란 데이터를 넣는 프로세스를 의미하고 소비자란 데이터를 꺼내는 프로세스를 말합니다.
이러한 두 협력 프로세스 사이에 버퍼를 두고 생산자와 소비자의 상황을 다루는 문제입니다.
위와 같은 상황에서 두 프로세스는 독립적으로 수행되지만 버퍼라는 공유자원을 사용해야 합니다.
이때 버퍼가 빈 경우, 가득 찬 경우 등의 문제를 고려해야 합니다.
문제의 조건
- 버퍼에 여러 프로세스가 동시에 접근할 수 없음
- 버퍼에 데이터를 넣는 동안 꺼낼 수 없고 꺼내는 동안 넣을 수 없음
- 버퍼의 크기는 유한함(유한 버퍼 문제)
- 버퍼가 가득 찬 경우 생산자는 대기
- 버퍼가 빈 경우 소비자는 대기
여기서 1번은 앞에서 보았던 상호배제 문제가 바로 떠오르실 겁니다.
그리고 2번은 동기화가 필요하겠죠.
해결
먼저 상호배제 문제부터 살펴보겠습니다.
버퍼에 데이터를 넣고 빼는 코드 부분은 동시에 수행될 수 없기 때문에 임계영역으로 설정되어야 합니다.
먼저 세마포어 mutex = 1로 초기값을 뮤텍스를 초기화하겠습니다.
지난번과 같이 버퍼 진입 영역에 P 연산을, 종료 영역에 V 연산을 배치하면 상호배제 문제를 해결할 수 있을 것입니다.
P연산은 감소연산 V연산은 증가연산이라고 말씀드린 적이 있습니다.
생산자는 데이터를 생산해 데이터를 임계영역의 버퍼에 집어넣고, 소비자는 버퍼에서 데이터를 꺼내 소비합니다.
하지만 이런 경우에 버퍼가 비거나 가득 차있어도 임계영역에 진입하게 됩니다.
이러한 동기화 문제를 해결하기 위해 세마포어를 더 사용해야 합니다.
버퍼가 가득 찬 경우
동기화를 위하여 세마포어 empty를 생성하고 초기값을 버퍼의 크기인 n으로 설정하겠습니다.
데이터를 넣기 전 P(empty) 연산으로 버퍼의 상태를 확인합니다.
버퍼가 가득 찬 상황이라면 empty는 0이 될 것이고 그럼 생산자는 대기해야 합니다.
그러한 상황이 아니라면 P연산으로 세마포어 값을 증가시킨 후 버퍼에 데이터를 삽입하게 됩니다.
반대로 소비자 측은 버퍼에서 데이터를 꺼낸 후 전 V(empty) 연산을 수행하며 세마포어의 값을 낮춰줍니다..
반대의 경우도 생각해 보겠습니다.
버퍼가 빈 경우
동기화를 위해 세마포어 full=0으로 초기화를 시켜주겠습니다.
생산자는 데이터를 넣은 후 V(full)로 세마포어 값을 증가시킵니다.
소비자는 데이터를 꺼낸 후 P(full) 연산으로 세마포어값을 감소시킵니다.
판독기-기록기 문제
판독기는 데이터를 읽는 프로세스, 기록기는 데이터를 쓰는 프로세스를 뜻합니다.
이 문제는 여러 협력 프로세스 사이에 공유자원을 두고 판독기와 기록기의 상황을 다루는 문제입니다.
공유자원을 두고 공유자원을 쓰는 여러 개의 판독기와 여러개의 기록기가 존재할 수 있는데요.
판독기가 데이터를 읽는 경우에는 공유자원에 아무런 영향이 없습니다.
반면 기록기는 공유자원에 변화를 주게 됩니다.
문제조건
- 하나의 기록기가 공유자원에 데이터를 쓰는 경우에 다른 기록기나 판독기는 공유자원 접근 불가
- 공유자원에 데이터 작성 중에는 누구도 접근 불가
- 공유자원에서 데이터를 읽는 동안에는 데이터 쓰기 불가
- 여러 판독기는 동시에 공유자원에서 데이터 읽기 가능
- 판독기가 읽는 중 새로운 판독기가 데이터 읽기 시도 가능
- 판독기가 읽는 중에는 기록기 대기 (새로운 판독기가 읽기 시도할 때 가능 여부는 상황에 따라 정의 가능)
1번은 상호배제 조건입니다.
2번 조건에서는 '새로운 판독기가 읽기를 시도할때 가능 여부는 상황에 따라 정의 가능하다'는 문구가 있는데요.
해당 상황에 어디에 우선순위를 주는지에 따라서 문제는 제1 판독기-기록기, 제2 판독기-기록기 문제로 나뉘게 됩니다.
제1 판독기-기록기 문제
해당 문제에서는 판독기가 공유자원에 접근 중이라면 기록기보다 판독기에 우선순위를 부여합니다.
즉 새로운 판독기는 즉시 공유자원에 접근이 가능한 것입니다.
하지만 이경우 기록기의 기아상태를 유발할 가능성이 존재합니다.
새로운 판독기가 계속해서 들어오게 된다면 기록기는 계속 대기만 해야 하는 상황이 발생하는 것이죠.
해결
먼저 상호배제 문제부터 해결해 보겠습니다.
세마포어 wrt의 초기값을 1로 설정하여 생성합니다.
판독기와 기록기는 각각 쓰기/읽기 전에 P연산을 수행하고 작업을 마치고 V연산을 수행합니다.
하지만 이런 경우 판독기가 읽는 중에 다른 판독기가 읽기를 수행할 수 있습니다.
해서 판독기에 우선을 주기 위해 일반변수 count(초기값 0)을 생성하여 읽으려는 판독기의 개수를 표현했습니다.
하지만 동시에 들어온 경우 count 변수가 0에서 2로 변경될 수 있습니다.
해서 count 변수를 높이고 체크하는 것 자체를 하나의 세마포어로 보는 것이 필요합니다.
해당 코드 앞뒤로 새로운 뮤텍스 mutex를 구성하여 문제를 해결할 수 있습니다.
제2 판독기-기록기 문제
판독기가 공유자원에 접근 중이라면 판독기보다 기록기에 우선순위를 부여합니다.
대기 중인 기록기가 있다면 새로운 판독기는 공유자원 접근 불가능합니다.
하지만 제1 판독기-기록기 문제와 반대로 판독기의 기아상태를 유발할 수 있고 판독기의 병행성을 저하시킬 수 있다는 문제점이 있습니다.
해결
이 문제는 총 5개의 뮤텍스와 두 개의 일반 변수를 이용해 해결하게 됩니다.
- 공유자원 상호배제를 위한 세마포어 wrt
- 기록기 기록 시 추가적인 기록기가 대기하는 경우를 위한 변수 wCount
- 기록기의 증가를 하나의 세마포어로 취급하기 위한 wMutex
- 기록기 대기 시 판독기의 뮤텍스 진입을 막는 세마포어 rd
- 판독기 개수 파악을 위한 변수 rCount
- 판독기의 증가를 하나의 세마포어로 취급하기 위한 rMutex
- 너무 많은 판독기가 대기하지 않도록 판독기 진입을 막기 위한 mutex
위와 같이 구성한다면 한 개씩의 기록기와 판독기만 대기할 수 있는 구조로 구현할 수 있습니다.
통신문제
먼저 프로세스 간 통신(IPC, Inter Process Communication)이란 프로세스들 사이에 서로 데이터를 주고받는 행위 또는 그에 대한 방법이나 경로를 뜻합니다.
협력 프로세스 사이에는 데이터를 공유하기 위해 통신이 필수이며 이 과정에서도 다양한 문제가 발생할 수 있는데요.
병행 프로세스 사이의 통신을 위한 방법에 대해 논리적 측면에서 살펴보겠습니다.
병행 프로세스가 데이터를 서로 공유하는 방법은 공유메모리 방법과 메시지 전달 방법 두 가지가 있는데요.
하나의 운영체제에서 두 가지 방법 함께 사용하는 것도 가능합니다.
공유메모리방식
협력프로세스가 공유자원인 메모리 공간에 있는 동일 변수를 사용합니다.
예) 생산자-소비자 문제의 버퍼, 판독기-기록기 문제의 공유자원
위 방식의 장점은 대량의 데이터 교환과 고속통신이 가능하다는 점입니다.
하지만 통신상 발생 가능한 다양한 문제(생산자-소비자 문제 등)가 존재하고 해당 문제들은 모두 응용프로그래머가 해결해야 한다는 단점이 존재합니다.
메시지전달방식
협력프로세스가 메시지를 주고받는 방식 데이터를 서로 공유하며 시스템 호출인 send()와 receive()를 이용합니다.
소량의 데이터 교환에 적합한 방식으로 통신상 발생 가능한 문제(상호배제 등)는 운영체제가 해결해 준다는 장점이 있습니다.
그럼 운영체제는 메시지를 어떻게 전달하는 걸까요?
운영체제 메세지 전달방법의 논리적 구조
먼저 프로세스 사이의 메세지 전달 통로를 통신링크라 합니다.
이 통신 링크의 구현 형태를 살펴보면 다음과 같습니다.
연결 대상
- 둘 이상의 프로세스
두 프로세스 사이의 링크 개수
- 하나 이상
방향성
- 단방향
- 양방향
용량
- 0
- 큐가 존재하지 않음
- 송신자는 수신자가 메시지를 받을 수 있을 때까지 대기
- 무한
- 큐의 크기가 무한함
- 송신자는 대기 없이 계속 전송
- 유한
- 큐의 크기가 유한함
- 송신자는 큐가 가득 차면 대기
메세지 전달 방식
- 직접통신
- 두 프로세스가 직접 서로를 지정해 메세지 전달(send, receive 시 전달할 프로세스 지정)
- 오직 하나의 양방향 통신 링크가 자동 설정되며 통신링크는 오직 두 프로세스 사이에만 연관
- 주소지정방식에는 대칭형과 비대칭형 존재
- 대칭형
- 서로의 주소 지정
- 비대칭형
- 보내는 것만 주소 지정, 받는 쪽은 누구한테 받을지 모르기 때문에 변수 사용
- 수신자가 여러 송신자와 통신 링크를 갖는 경우 사용 (한 프로세스가 여러 프로세스로부터 메시지를 받을 수 있는 경우)
- 대칭형
- 간접통신
- 두 프로세스 사이에 둔 우편함을 통해 메세지를 전달(send, receive 둘 다 우편함으로 지정)
- 같은 우편함을 이용한 경우 통신링크가 설정되며 여러 우편함 이용 시 여러 개의 통신 링크 존재
- 하나의 통신링크가 여러 프로세스와 연관 가능
- 양방향 / 단방향 통신링크 둘 다 가능
- 양방향
- 우편함이 운영체제에 소속되며 운영체제가 수신자 관리
- 수신자가 여럿이지만 한순간에 하나의 수신자만 수신 가능
- 양방향 통신링크
- 단방향
- 우편함이 수신 프로세스에 소속되며 수신프로세스 종료 시 우편함도 사라짐
- 수신프로세스는 다른 프로세스들이 보낸 메시지를 받아만 볼 수 있음
- 수신자 1 (자신이 유일한 수신자)
- 단방향 통신링크
- 양방향
'Computer Science > OS' 카테고리의 다른 글
교착 상태 처리 기법 (2) | 2023.04.25 |
---|---|
[OS] 교착 상태 (0) | 2023.04.24 |
[OS] 병행성 문제 (0) | 2023.04.23 |
[OS] 병행프로세스 (0) | 2023.04.17 |
[OS] 프로세스 스케줄링 알고리즘 (0) | 2023.03.15 |