프로세스 간 통신의 개념
- 프로세스 내부 데이터 통신
- 하나의 프로세스 내에 2개 이상의 스레드가 존재하여, 전역 변수나 파일을 이용해 데이터를 주고 받는다.
- 프로세스 간 데이터 통신
- 같은 컴퓨터에 있는 여러 프로세스끼리 통신하는 경우로, 공용 파일 또는 운영체제가 제공하는 파이프를 사용하여 통신한다.
- 네트워크를 이용한 데이터 통신 : 여러 컴퓨터가 네트워크로 연결되어 있을 때의 통신 방식으로, 소켓을 이용해 통신한다. 이를 네트워킹이라고 한다. 원격 프로시져 콜도 이에 해당한다.
프로세스 간 통신의 분류
통신 방향에 따른 분류
- 양방향 통신
- 데이터를 동시에 양쪽 방향으로 전송할 수 있는 구조. 소켓 통신이 이에 해당한다.
- 반양방향 통신
- 양쪽 방향 모두에 전송할 수 있지만, 동시 전송은 불가능한 경우. 무전기가 이에 해당한다.
- 단방향 통신
- 한쪽 방향으로만 데이터를 전송할 수 있는 구조. 전역 변수나 파이프가 이에 해당한다.
통신 구현 방식에 따른 분류
- 전역 변수를 이용한 통신의 문제는 언제 데이터를 보낼 지 받는 쪽에서 모르는 것
- 따라서 상태 변화를 살펴보기 위해 반복문을 무한 실행하며 기다리는 것 = busy waiting
- 이 문제를 해결하기 위해서 데이터가 도착했음을 알리는 동기화를 사용
- 대기가 있는 통신
- 동기화를 지원하는 통신 방식. 데이터를 받는 쪽은 데이터가 도착할 때까지 자동으로 대기 상태에 모무른다.
- 대기가 없는 통신
- 동기화를 지원하지 않는다. 데이터를 받는 쪽은 busy waiting를 사용해 데이터 도착 여부를 직접 확인한다.
- 대기가 있는 통신
프로세스 간 통신의 종류
전역 변수를 이용한 통신
- 공동으로 관리하는 메모리를 사용하여 데이터를 주고받는 것
- 주로 직접적으로 관련이 있는 프로세스 간에 사용
- busy waiting를 통해 계속 전역 변수의 값을 확인해야하므로 비효율적이다.
파일을 이용한 통신
- 파일 열기
- open()을 통해 사용하려는 파일이 있는지, 권한을 어떻게 줄 것인지 결정.
- 읽기 또는 쓰기
- fd를 이용해 write(fd, "string", size), read(fd, str, size) 함수를 사용
- 파일 닫기
- close(fd)를 통해 파일을 닫기
- 프로세스가 입출력 관리 프로세스에 읽기/쓰기를 요구하면 데이터가 하드디스크에 출력/저장된다.
- 따라서 파일 입출력 또한 프로세스와 입출력 프로세스 간의 통신이라고 할 수 있다.
파이프를 이용한 통신
- 파이프는 운영체제가 제공하는 동기화 통신 방식
- open() 함수로 기술자를 얻고 작업을 한 후 close() 함수로 마무리
- 전역 변수 통신과 마찬가지로 단방향 통신이고 따라서 파이프를 2개를 사용해야 한다.
- 이름 없는 파이프
- 일반적인 파이프, 부모와 자식, 혹은 형제 프로세스같이 서로 관련 있는 프로세스 간 통신에 사용
- 이름 있는 파이프
- FIFO라 불리는 특수 파일을 이용해 서로 관련 없는 프로세스 간 통신에 사용.
소켓을 이용한 통신
- 네트워킹
- 여러 컴퓨터에 있는 프로세스 간 통신
- 네트워킹에서의 통신은 원격 프로시져 콜이나 소켓을 이용
- RPC
- 다른 컴퓨터에 있는 함수를 호출
- 일반적으로 원격 프로시져 콜은 소켓을 이용해 구현
- 바인딩
- 소켓을 매개로 한 쪽의 프로세스와 다른쪽의 프로세스를 연결하는 작업
- 소켓은 한개만 사용해도 양방향 통신이 가능
공유자원의 접근
- 공유 자원(shared resource)
- 여러 프로세스가 공동으로 이용하는 변수, 메모리, 파일
- 공유 자원은 공동으로 이용되기 때문에 경우에 따라 결과가 달라질 수 있다.
- 레이스 컨디션
- 2개 이상의 프로세스가 공유 자원을 병행적으로 읽거나 쓰는 상황
임계구역
공유 자원 접근 순서에 따라 실행 결과가 달라지는 프로그램의 영역을 임계 구역(Critical Section)이라고 한다.
임계구역 해결 조건
- 상호 배제 (Mutual Exclusion)
- 한 프로세스가 임계구역에 들어가면 다른 프로세스는 임계구역에 들어갈 수 없다.
- 한정 대기(bounded waiting)
- 어떤 프로세스도 무한 대기 하지 않아야 한다.
- 진행의 융통성(progress flexibility)
- 한 프로세스가 다른 프로세스의 진행을 막아선 안 된다.
피터슨 알고리즘
- 피터슨 알고리즘은 임계구역 해결의 3가지 조건을 만족하지만 2개의 프로세스만 사용 가능하다는 한계가 있다.
- 여러 프로세스를 사용하려면 공유변수를 추가해야한다.
데커 알고리즘
- 하드웨어의 도움 없이도 임계구역 문제 해결 가능.
- 매우 복잡하다는 단점
세마포어
- 세마포어는 임계구역에 진입하기 전에 스위치를 사용 중으로 놓고 임계구역에 들어간다.
- 작업을 마치면 다음 프로세스에 동기화 신호를 보낸다.
Semaphore(n);
P();
/* 임계 구역 */
V();
- Semaphore(n) : 전역 변수 RS를 n으로 초기화 한다. RS는 현재 사용 가능한 자원의 수 이다.
- P() : 잠금을 수행하는 코드로 RS가 0보다 크면 1만큼 감소시키고 임계구역에 진입, 0보다 작으면 0보다 커질때까지 기다린다.
- V() : 잠금 해제와 동기화를 수행하는 코드로, RS를 1 증가시키고 wake_up 신호를 보낸다.
- 세마포어에서 잠금이 해제되기를 기다리는 프로세스들은 세마포어 큐에 저장되어 있다가 wake_up신호를 받고나서 큐에서 나와 임계구역에 진입한다.
- 따라서 busy waiting을 하는 프로세스가 없다.
모니터
- 세마포어의 큰 문제는 잘못된 사용으로 인해 임계구역이 보호받지 못한다는 것
- 모니터는 공유 자원을 내부적으로 숨기고 공유 자원에 접근하기 위한 인터페이스만 제공해서 자원을 보호하고 프로세스 간에 동기화를 시킨다. = 시스템 호출
monitor shared_balance{
private :
int balance = 10;
boolean busy=false;
condition mon;
public :
increase(int amount) {
if(busy==true) mon.wait();
busy=true;
balance=balance+amount;
mon.signal();
}
}
- busy = 잠금 역할 / mon = 잠금 해제 역할 / 공유 변수 balance
- 이 변수는 increase()를 통해서만 값을 변경 가능.
- increase()는 임계구역이 잠겼는지 확인한 후 예금액을 증가시킨다.
- 모니터를 사용하면 P()와 V()를 사용할 필요가 없이 increase()만 사용하면 된다.
- 모니터는 임계구역 보호와 동기화를 위해 내부적으로 상태 변수를 사용
- wait() : 모니터 큐에서 자신의 차례가 올 때까지 기다린다. 세마포어의 P()에 해당한다.
- signal() : 모니터 큐에서 기다리는 다음 프로세스에 순서를 넘겨준다. 세마포어의 V()에 해당한다.
'CS > 운영체제' 카테고리의 다른 글
[운영체제] 물리 메모리 관리 (0) | 2024.03.26 |
---|---|
[운영체제] 교착 상태 (0) | 2024.03.26 |
[운영체제] CPU 스케줄링 (1) | 2024.03.26 |
[운영체제] 스레드 (0) | 2024.03.26 |
[운영체제] 프로세스 (0) | 2024.03.26 |