[OS] 7. 프로세스 간 통신(IPC)
프로세스 간 통신 (IPC)
- 프로세스는 시스템 내에서 독립적으로 실행되기도 하고 데이터를 주고받으며 협업하기도 한다.
- 프로세스 간 통신(IPC)은 데이터를 주거나 받는 동작으로 이루어지며, 이는 쓰기 연산과 읽기 연산으로 간소화할 수 있다.
- 모든 통신에 관련된 연산은
open()
,read()
,write()
,close()
구조이다.- 전역 변수, 파일을 사용한 통신은 운영체제의 도움없이 진행되는 통신 방식
- 파이프, 소켓, 원격 프로시저 호출 등은 운영체제가 제공하는 통신 방식
-
프로세스 간 통신의 개념
- 프로세스 내부 데이터 통신
- 하나의 프로세스 내에 2개 이상의 스레드가 존재하는 경우의 통신
- 전역 변수나 파일을 이용
- 프로세스 간 데이터 통신
- 같은 컴퓨터에 있는 여러 프로세스끼리 통신
- 공용 파일, 파이프를 사용
- 네트워크를 이용한 데이터 통신
- 여러 컴퓨터가 네트워크로 연결되어있을 경우 통신
- 소켓, 원격 프로시저 호출을 사용
- 소켓을 사용하는 프로세스간 통신을 네트워킹 이라고 한다.
- 프로세스 내부 데이터 통신
프로세스 간 통신의 분류
분류 방식 | 종류 | 예시 |
---|---|---|
통신 방향 | 양방향 통신 | 일반적 통신, 소켓 |
반양방향 통신 | 무전기 | |
단방향 통신 | 전역 변수, 파일, 파이프 | |
통신 구현 방식 | 대기가 있는 통신(동기화) | 파이프, 소켓 |
대기가 없는 통신(비동기화) | 전역 변수, 파일 |
- 반양방향 통신은 데이터를 양쪽 방향으로 전송할 수 있지만, 동시 전송은 불가능하고 특정 시점에 한쪽 방향으로만 전송할 수 있는 구조
전역 변수를 이용한 통신
-
공동으로 관리하는 메모리를 사용하여 데이터를 주고 받는다.
- 데이터를 보내는 쪽에서는 전역변수나 파일에 값을 쓰고, 데이터를 받는 쪽에서는 전역변수의 값을 읽는다.
- 직접적인 관련이 있는 프로세스 간에 사용한다.
- e.g. 부모 프로세스가 전역 변수를 선언한 후 자식 프로세스를 만들면 부모 프로세스와 자식 프로세스가 통신을 할 수 있다.
- 전역변수를 사용하는 통신 방식의 문제점은, 언제 데이터를 보낼지 받는 쪽에서는 모른다는 것이다.
- 따라서 데이터를 받는 쪽에서 반복적으로 전역변수의 값을 점검해야한다.
- 상태 변화를 살피기 위해 반복문을 실행하며 기다리는 것을 바쁜 대기(busy waiting)라고 한다.
- 시스템 차원에서 큰 자원 낭비이므로 안 좋은 프로그래밍의 전형적인 예다.
- 바쁜 대기 문제를 해결하기 위해서 동기화(synchronization)를 사용한다.
- 동기화를 사용하면 바쁜 대기를 하지 않아도 데이터가 도착했음을 운영체제가 알려준다.
- e.g. 메신저에서 메세지가 도착했다고 알려주는 알림
동기화 통신 vs. 비동기화 통신
- 동기화 통신
- 동기화를 지원하는 방식
- 데이터를 받는 쪽은 데이터가 도착할 때까지 자동으로 대기 상태에 머물러있다.
open()
,close()
함수를 사용한다.open()
: 키 또는 권한(descriptor)를 받아 작업을 시작close()
: 자원을 다 사용하면 키를 반납
- 비동기화 통신
- 동기화를 지원하지 않는 방식
- 데이터를 받는 쪽은 바쁜 대기를 사용하여 데이터의 도착 여부를 확인한다.
파일을 이용한 통신
-
파일(전역변수) 입출력 코드는 크게
open
,write
,read
,close
로 이루어져 있다. - 부모-자식 관계 프로세스 간 통신에 많이 사용된다.
- 동기화를 제공하지 않는다.
- 파일 내의 데이터는 한 줄로 길게 저장된다. 즉 순차 파일(Sequential File) 이다.
- 순차 파일에 접근 하는 방식을 순차적 접근(Sequential Access)이라고 한다.
- 운영체제가 동기화를 지원하지 않기 때문에, 부모-자식 프로세스 관계라면, 부모 프로세스가
wait()
을 사용하여 자식 프로세스가 작업을 끝낼 때까지 기다렸다가 작업을 시작한다. read()
와write()
가 파일 기술자를 공유한다. 따라서read()
를 하건write()
를 하건 상관없이 기술자가 전진하여 동기화를 할 수 없다.- 파일 열기
open()
을 이용하여 사용하고자 하는 파일이 있는지, 파일이 있다면 쓰기 권한이 있는지 확인open(”test.txt”, O_RDWR)
O_RDWR
: 읽기/쓰기 작업O_RDONLY
: 읽기 전용
- 정상적으로 파일을 사용할 수 있다면,
open()
은fd
를 반환- fd(File Descriptor)는 어떤 파일에 접근할 수 있는 권한으로, 파일 기술자라고 한다.
- 어떤 파일에 쓰기/읽기 연산을 하려면 먼저
fd
를 얻어야하며 작업이 끝나면fd
를 돌려줘야한다.
- 읽기/쓰기 연산
write(fd, ‘Test’, 5)
: 파일에 test 를 쓰라는 뜻이다. Test 의 크기가5B
이기 때문에 5 를 명시read(fd, buf, 5)
: 파일에서5B
를 읽어 변수buf
에 저장
- 파일 닫기
close(fd)
:fd
가 가리키는 파일을 닫는다.
파이프를 이용한 통신
-
파이프는 운영체제가 제공하는 동기화 통신 방식으로 단방향이다. 파이프는 이름 있는 파이프와 이름 없는 파이프로 나뉜다.
- 파이프는 queue 와 같다. 따라서 한쪽에서는 write(push)하는 것이고, 한 쪽은 read(pop) 밖에 할 수가 없다.
- 즉 파이프에 쓰기 연산을 하면 데이터가 전송되고, 읽기 연산을 하면 데이터를 받는다.
- 파이프로 양방향 통신을 하려면 파이프 2개를 사용해야 한다.
read()
와write()
의 기술자가 따로 존재한다. 따라서 동기화가 가능하다.- 파일 기술자를
fd[2]
와 같이 2개의 원소를 가진 배열로 정의하는데, 원소 하나는 읽기용이고 하나는 쓰기용이다.
- 파일 기술자를
- 대기 상태
- 프로세스 B가 파이프 1에 대해 읽기 연산을 수행했는데 프로세스 A 가 파이프 1에 아직 쓰기 연산을 하지 않았다면 프로세스 B는 대기 상태가 된다.
- 대기 상태는 프로세스 A가 파이프 1에 데이터를 쓰는 순간 자동으로 풀려 동기화가 이루어진다.
- 프로세스 B는 바쁜 대기를 하지 않아도 된다.
- 이름 없는 파이프
- 일반적인 파이프
- 부모-자식 관계와 같이 서로 관련 있는 프로세스 간 통신에 사용
- 이름 있는 파이프
- FIFO 라 불리는 특수한 파일을 이용하며 서로 관련 없는 프로세스 간 통신에 사용
소켓을 이용한 통신
- 여러 컴퓨터에 있는 프로세스 간 통신은 네트워킹이라고 한다.
-
네트워킹은 원격 프로시저 호출(RPC)이나 소켓을 이용한다. 소켓은 프로세스 동기화를 지원하고 양방향 통신이 가능하다.
- 소켓은 하나만 사용해도 양방향 통신이 가능하다. 반면에 파이프의 경우, 양방향 통신을 하기 위해서는 파이프를 2개 사용해야 한다.
- 소켓을 사용하여 다른 컴퓨터와 통신을 하려면,
- IP 주소로 컴퓨터의 위치를 파악한다.
- 원격지의 시스템 내 여러 프로세스 중 어떤 프로세스와 통신을 할지 결정한다.
- 한 컴퓨터 내에는 여러 프로세스가 존재한다.
- 이 때 사용하는 구분 번호를 포트 번호(Port Number)라고 한다.
- 통신하고자 하는 프로세스는 소켓에 쓰기 연산을 하면 데이터가 전송되고 읽기 연산을 하면 데이터를 받는다.
- 클라이언트
socket()
connect()
read()/write()
close()
- 서버
socket()
bind()
- 소켓을 생성한 후, bind()를 사용하여 특정 포트에 새로운 소켓을 등록한다.
- 동시에 여러 클라이언트에 서비스 하기 위해 하나의 포트번호에 여러 개의 소켓을 생성한다.
- 소켓을 하나만 생성한다면 단 한사람에게 서비스를 할 수 있을 것이다.
listen()
accept()
- 클라이언트의 connect(), 즉 연결 요청을 기다리다가 여러 명의 클라이언트가 동시에 connect 를 하는 경우 그 중 하나를 골라서 작업을 한다.
- accept()가 되면 소켓 기술자(descriptor)가 생성되고 작업이 시작된다.
read()/write()
close()
- 작업이 끝나면, 소켓 기술자를 닫는다. 이후에 계속 클라이언트를 받아서 작업해야 하기 때문에 무한루프를 돈다.
- 원격 프로시저 호출(RPC, remote procedure call)
- 다른 컴퓨터에 있는 함수를 호출하는 것이다.
- 소켓을 이용하여 구현한다.
- e.g. 자바같은 객체 지향 언어에서 다른 컴퓨터에 있는 객체의 메소드를 불러와 사용
공유 메모리(Shared Memory)
-
공유 메모리는 프로세스간 메모리 영역을 공유해서 사용할 수 있도록 허용한다.
출처 : https://velog.velcdn.com
- 프로세스가 공유 메모리 할당을 커널에 요청하면 커널은 해당 프로세스에 메모리 공간을 할당한다.
- 이후 어떤 프로세스건 해당 메모리 영역에 접근할 수 있다.
- 프로세스 간
read
와write
를 모두 필요로 할 때 사용한다. - 중개자 없이 곧바로 메모리에 접근할 수 있기 때문에 모든 IPC 중에서 가장 빠르게 작동한다.
파이프(Pipe)
-
통신을 위한 메모리 공간(버퍼)을 생성하여 프로세스가 데이터를 주고 받게끔 한다.
출처 : https://velog.velcdn.com
-
파이프는 익명 파이프와 네임드 파이프 2가지로 나뉘어진다.
- 익명 파이프(Anonymous PIPE)
- 일반적인 파이프
- 통신할 프로세스가 명확하게 알 수 있는 경우 사용한다.
- 파이프는 두 개의 프로세스를 연결하고, 하나의 프로세스는 데이터를 쓰기만, 다른 하나는 데이터를 읽기만 할 수 있다.
- 한 쪽 방향으로만 통신이 가능한 파이프의 특징 때문에 반이중통신이라고 부르기도 한다.
- 송/수신을 모두 하기 원한다면 두 개의 파이프를 만들어야 가능하다.
- 간단하게 사용이 가능하고,
pipe
함수로 생성한다. - 단점
- 반이중 통신이라 프로세스가 읽기와 쓰기 통신을 모두 해야한다면, PIPE 두 개를 만들어야 하므로, 구현이 복잡해질 수 있다.
- 전이중 통신을 고려해야 할 상황이라면 낭비가 심하게 때문에 좋은 선택이 아니다.
- 네임드 파이프(Named PIPE)
- 전혀 모르는 상태의 프로세스들 사이의 통신에 사용
- 익명 파이프의 확장된 상태로 부모 프로세스와 무관한 다른 프로세스도 통신 가능하다.
- 프로세스 통신을 위해 이름이 있는 파일을 사용하기 때문에 가능하다.
- FIFO 라 불리는 특수 파일을 이용해 서로 관련 없는 프로세스 간 통신에 사용한다.
- 외부 프로세스와 통신 가능
mkfifo
또는mknod
함수로 생성 가능.- 단점
- 익명 파이프와 같이 반이중통신이라는 단점이 있다.
- 익명 파이프(Anonymous PIPE)
소켓(Socket)
-
유닉스 도메인 소켓 또는 IPC 소켓은 동일한 호스트 운영체제에서 실행되는 프로세스 간 데이터를 교환하기 위한 데이터 통신 엔드 포인트이다.
출처 : https://velog.velcdn.com
- 네트워크 소켓 통신을 통해 데이터를 공유한다.
- 클라이언트와 서버가 소켓을 통해서 통신하는 구조로, 원격에서 프로세스 간 데이터를 공유할 때 사용한다.
- 전이중(양방향)통신이 가능하다.
- 서버/클라이언트 환경을 구축하는데 용이하다.
- 중대형 어플리케이션에서 주로 사용한다.
메시지 큐(Message Queue)
-
입출력 방식은 이름있는 파이프와 동일하다.
출처 : https://velog.velcdn.com
- 이름있는 파이프와 다른 점
- 메시지 큐는 파이프처럼 데이터의 흐름이 아니라 메모리 공간을 사용한다.
- PIPE 나 FIFO 와는 달리 다수의 프로세스간 메세지를 전달 할 수 있다.
- 사용할 데이터에 번호를 붙이면서 여러 프로세스가 동시에 데이터를 쉽게 다룰 수 있다.
- 메시지의 접근을 위해서는 키가 필요하다.
메모리 맵(Memory Map)
-
공유 메모리처럼 메모리를 공유해준다.
출처 : https://velog.velcdn.com
- 메모리 맵은 열린 파일을 메모리에 맵핑시켜서 공유하는 방식이다.
- 주로 파일로 대용량 데이터를 공유해야 할 때 사용한다.
- FILE IO가 느릴 때 사용하면 좋다.
- 대부분의 운영체제에서는 프로세스를 실행할 때 실행 파일의 각 세그먼트를 메모리에 사상하기 위해 메모리 맵 파일을 이용한다.
- 메모리 맵 파일은 파일의 크기를 바꿀 수는 없으며 메모리 맵 파일을 사용하기 이전, 또는 이후에만 파일의 크기를 바꿀 수 있다.
댓글 남기기