프로세스간 통신의 종류
프로세스 내부 데이터 통신: 하나의 프로세스 내에 2개 이상의 스레드가 공유 자원을 통해 데이터를 주고 받는 것이다.
프로세스 간 데이터 통신: 같은 컴퓨터에 있는 프로세스들 간에 데이터 통신을 의미한다. 공유 파일 또는 운영체제가 제공하는 파이프를 사용하여 통신한다.
네트워크를 이용한 데이터 통신: 여러 컴퓨터가 네트워크로 연결되어 데이터를 주고 받는 것을 의미한다. 이 경우에는 소켓을 이용하여 데이터를 주고 받는다.
통신의 종류
여기서 더 자세히 알아볼 것은 단방향 통신의 통신법이다.
전역 변수를 통한 통신은 단방향 통신이다. 이를 양방향 통신으로 구현하려면 전역변수를 2개 사용해야한다.
전역 변수를 사용한 통신의 가장 큰 문제는 프로세스끼리 데이터를 주고 받을 때, 언제 데이터가 왔는지 알 수가 없다는 문제이다. 받는 프로세스가 데이터가 언제 왔는지 알기 위해 반복문으르 무한 실행하며 기다리는 것을 바쁜대기라고 한다.
통신은 대기가 있는 동기화 통신과 대기가 없는 비동기화 통신으로 나뉜다.
동기화 통신은 데이터가 도착하였을 때 바쁜대기를 하지 않아도 운영체제가 알아서 알려주는 것이다.
비동기화 통신은 데이터를 받는 쪽에서 바쁜 대기를 통하여 데이터가 도착했는지 여부를 직접 확인 해야한다.
공유자원이란
공유자원은 여러 프로세스가 공동으로 이용하는 데이터를 말한다.
공유자원은 누가 언제 데이터를 읽거나 쓰느냐에 따라 그 결과가 달라질 수 있다.
2개 이상의 프로세스가 공유자원을 병행적으로 읽거나 쓰는 상황을 경쟁 조건이 발생했다고 한다.
임계구역이란
공유 자원 접근 순서에 따라 실행 결과가 달라지는 프로그램의 영역을 임계구역이라고 한다.
임계구역에서 프로세스들은 동시에 작업해서는 안된다. 이를 해결하기 위해 한 프로세스가 임계구역에 들어가면 다른 프로세스들은 임계구역 밖에서 기다려야한다.
임계구역의 해결 조건
임계구역 문제를 해결하는 방법은 세 가지 조건을 만족해야한다.
상호배제, 한정 대기, 진행의 융통성이다.
상호배제: 한 프로세스가 임계구역에 들어가면 다른 프로세스는 임계구역에 드르어갈 수 없는 것이다.
한정대기: 어떤 프로세스도 무한대기를 하지 않아야 하나다.
진행의 융통성: 한 프로세스가 다른 프로세스의 작업을 방해해서는 안되는 것이다.
임계구역을 해결하는 방법들
1. Lock
임계구역을 해결하는 가장 간단한 방법으으로 boolean형태와 같은 변수로 임계구역을 다른 프로세스가 작업하는 동안 while(lock == true); 와 같은 코드로 해당 임계구역을 처리하지 못하게 방지하는 방법이다.
하지만 이 방법에는 문제가 있다. 우선 기본적인 배경지식을 다시 한번 상기시키겠다. 시분할 처리 시스템에서는 프로세스들을 작업단위를 잘게 쪼개어 처리한다.
또한 CPU 멀티스레드를 통해 스레드를 파이프라인 기법을 이용하여 동시에 여러 스레드를 처리하도록 만든 병렬 처리 기법이 있다.
한 예시로 lock = true를 통해 한 스레드가 작업을 하다가 작업을 끝내면 lock = false를 통해 끝냈다는 표시를 하는 lock방식이 있다고 가정하자. lock = true를 하고 작업을 진행한 후, lock = false를 하기 전에 프로세스가 타임 슬라이스가 다되어 준비상태로 갔다가 다시 실행상태로 와서 작업을 처리한다. 이때 작업을 하던 스레드도 lock = true로 되어있어서 해당 스레드도 작업을 하지 못하는 상황이 발생한다.
2. 피터슨 알고리즘, 데커 알고리즘
이를 해결하기 위해 피터슨, 데커 알고리즘이 있지만, 프로세스가 늘어나면 변수도 늘어나고 전체적인 알고리즘이 복잡해 지기 때문에 바람직한 접근 방법이 아니었다.
3. 세마포어
이를 해결하기 위해 세마포어 알고리즘이 나왔다.
세마파어는 임계구역에 진입하기 전에 스위치를 사용 중으로 놓고 임계구역에 들어간다. 이후에 도착하는 프로세스는 앞의 프로세스가 작업을 마칠 때까지 기다린다. 프로세스가 작업을 마치면 다음 프로세스에 임계구역을 사용하라는 동기화 신호를 보낸다.
세마포어는 사용 전에 초기 설정 Semaphore(n)을 한다. 이때 n은 공유 가능한 자원의 수를 나타낸다.
진행 과정은 Semaphore(n)과 P(), V()를 사용하여 진행된다.
Semaphore(n): 전역변수 RS를 n으로 초기화 한다. RS는 현재 사용 가능한 자원의 수가 저장된다.
P(): 잠금을 수행하는 코드로 RS가 0보다 크면 1만큼 감소시키고 임계구역에 진입한다. 만약 RS가 0보다 작으면 0보다 커질 때까지 기다린다.
V(): 잠금해제와 동기화를 같이 수행하는 코드로, RS값을 1증가시키고 세마포어에서 기다리는 프로세스에게 임계구역에 진입해도 좋다는 wake_up신호를 보낸다.
세마포어에서 잠금이 해제되기를 기다리는 프로세스는 세마포어 큐에 저장되어 있다가 wake_up신호를 받으면 큐에서 나와 임계구역에 진입한다. 즉, 바쁜 대기를 하는 프로세스가 없다.
그러나 세마포어의 P()나 V() 내부 코드가 실행되는 도중에 다른 코드가 실행되면 상호 배제와 한정 대기 조건을 보장받지 못하기 때문에 내부 코드는 검사와 지정을 사용하여 분리 실행되지 않고 완전히 실행되게 해야한다.
4. 모니터
하지만 이러한 세마포어에도 문제점이 있다. 바로 잘못된 사용으로 인해 임계구역이 보호받지 못한다는 것이다.
개발자가 실수로 잘못된 사용을 할 문제점이 발생할 수 있다는 것이다.
이를 해결하기 위해
--- 아 이거 아닌거 같은데,,