티스토리 뷰
프로세스간 커뮤니케이션
프로세스들이 서로의 공간을 쉽게 접근할 수 있다면?
프로세스 데이터/코드가 바뀔 수 있으니 얼마나 위험할까?
- 프로세스는 다른 프로세스의 공간을 접근할 수 없다.
IPC(Inter Process Communication)
- 프로세스간에 커뮤니케이션을 해야한다면 어떻게 해야할까?
- IPC를 이용한 프로세스간 통신방법을 제공함\
프로세스간 통신이 필요할까?
- 성능을 높이기 위해 여러 프로세스를 만들어 동시 실행
- 이 때 프로세스간 상태 확인 데이터 송수신이 필요
Fork() 시스템콜
- fork() 함수로 프로세스 자신을 복사해서 새로운 프로세스로 만들 수 있음
- 부모 프로세스, 자식 프로세스
- 프로세스를 fork()해서, 여러 프로세스를 동시에 실행시킬 수 있음
- 보통은 CPU가 한개 일때만 생각하지만,
- 최근에는 CPU안에 코어가 8개 되는 경우도 많고, 각 프로세스를 각 코어에 동시에 실행 가능하다. (병렬 처리)
- Ex) 여러 프로세스 동시 실행하기
- 1~10000까지 더하기
- fork()함수로 10개 프로세스 만들어서, 각각 1
1000, 10012000, ... 더하기 - 각각 더한 값을 모두 합하면, 더 빠르게 동작 가능하다.
- 단, 이 때 각 프로세스가 더한 값을 수집해야 하므로, 프로세스간 통신이 필요하다.
- fork()함수로 10개 프로세스 만들어서, 각각 1
- 1~10000까지 더하기
- Ex) 웹서버
- 웹서버 만들기
- 새로운 사용자 요청이 올 때마다, fork()함수로 새로운 프로세스를 만들고, 각 사용자 요청에 즉시 대응
- CPU 병렬 처리가 가능하다면, 더 빠른 대응이 가능하다.
- 단, 이 때 각 프로세스 제어 및 상태 정보 교환을 위해 프로세스간 통신이 필요하다.
- 웹서버 만들기
파일을 사용한 커뮤니케이션
- 프로세스간 통신을 위해서 File을 사용한다.
- 간단히 다른 프로세스에 전달할 내용을 파일에 쓰고, 다른 프로세스가 해당 파일을 읽으면 된다.
- File을 사용하면, 실시간 직접 원하는 프로세스에 데이터 전달이 어렵다.
- 해당 프로세스가 파일을 읽어야 하는데... 계속 실시간으로 읽고만 있을수가 없다..ㅠㅠ
- 그래서... 보다 다양한 IPC 기법이 있다.
실제 프로세스: 리눅스
- 프로세스간 공간은 완전히 분리되어 있다.
- 사용자 모드에서 커널 공간 접근은 불가하다.
- 그러나 커널 공간은 공유가 가능하다.
- 가상메모리에서 확인할 수 있다.
다양한 IPC 기법
- File 사용하기
- 커널 공간을 사용하기 - 핵심
- Message Queue
- Shared Memory
- Pipe
- Signal
- Semaphore
- Socket
파이프
- 기본 파이프는 단방향 통신
- fork()로 자식 프로세스를 만들었을 때, 부모와 자식간의 통신
파이프 코드 예제
char* msg = "Hello Child Process!";
int main()
{
char buf[255];
int fd[2], pid, nbytes;
if (pipe(fd) < 0) // pipe(fd)로 파이프 생성
exit(1);
pid = fork(); // 이 함수 실행 다음 코드부터 부보/자식 프로세스로 나뉘어짐
if (pid > 0) { // 부모 프로세스는 Pid에 실제 프로세스 ID가 들어간다.
write(fd[1], msg, MSGSIZE); //fd[1]에 쓰기
exit(0);
}
else { // 자식 프로세스는 Pid에 0이 들어간다.
nbytes = read(fd[0], buf, MSGSIZE); // fd[0]으로 읽음
printf("%d %s\n", nbytes, buf);
exit(0);
}
return 0;
}
메시지 큐(message queue)
- 큐니까, 기본으로 FIFO 정책으로 데이터 전송
- 어느 프로세스간에라도 데이터 송수긴이 가능하다.
- 먼저 넣은 데이터가 먼저 읽혀진다.
메시지 큐 코드 예제
// A 프로세스
msqid = msgget(key, msgflg) // key는 1234, msgflg는 옵션
msgsnd(msqid, &sbuf, buf_length, IPC_NOWAIT)
// B 프로세스
msqid = msgget(key, msgflg) // key는 동일하게 1234로 해야 해당 큐의 msgid를 얻을 수 있다.
msgrcv(msqid, &rbuf, MSGSZ, 1, 0)
공유 메모리(shared memory)
- 노골적으로 kernel space에 메모리 공간을 만들고, 해당 공간을 변수처럼 쓰는 방식
- message queue처럼 FIFO방식이 아니라, 해당 메모리 주소를 마치 변수처럼 접근하는 방식
- 공유 메모리 Key를 가지고 여러 프로세스가 접근이 가능하다.
공유 메모리 코드 예제
- 공유 메모리 생성 및 공유 메모리 주소얻기
- 공유 메모리에 쓰기
- 공유 메모리에서 읽기
시그널
- 유닉스에서 30년 이상 사용된 전통적인 기법
- 커널 또는 프로세스에서 다른 프로세스에 어떤 이벤트가 발생되었는지를 알려주는 기법
- 프로세스 관련 코드에 관련 시그널 핸들러를 등록해서, 해당 시그널을 실행
- 시그널 무시
- 시그널 블록(블록을 푸는 순간, 프로세스에 해당 시그널 전달)
- 등록된 시그널 핸들러로 특정 동작 수행
- 등록된 시그널 핸들러가 없다면, 커널에서 기본 동작 수행
주요 시그널
- SIGKILL: 프로세스를 죽여라(슈퍼 관리자가 사용하는 시그널로, 프로세스는 어떤 경우든 죽도록 되어 있다)
- SIGALARM: 알람을 발생시킨다.
- SIGSTP: 프로세스를 멈춰라
- SIGCONT: 멈춰진 프로세스를 실행하라.
- SIGINT: 프로세스에 인터럽트를 보내서 프로세스를 죽여라
- SIGSEGV: 프로세스가 다른 메모리영역을 침범했다.
시그널과 프로세스
- PCB에 해당 프로세스가 블록 또는 처리해야하는 시그널 관련 정보 관리
소켓
- 소켓은 네트워크 통신을 위한 기술
- 기본적으로 클라이언트와 서버등 두 개의 다른 컴퓨터간의 네트워크 기반 통신을 위한 기술
- 하나의 컴퓨터 안에서 소켓을 이용하여, 두 개의 프로세스간에 통신 기법으로 사용가능하다.
정리
- 다양한 IPC기법을 활용해서, 프로세스간 통신이 가능하다.
- IPC 기법 이외에도 사용할 수 있는 두가지 기술 개념을 이해한다.
- 시그널(signal)
- 소켓
패스트캠프 강의를 듣고 정리했습니다.
'개발 > 상식' 카테고리의 다른 글
[운영체제] 6. 프로세스 구조 (0) | 2019.12.19 |
---|---|
[운영체제] 5. 인터럽트 (0) | 2019.12.19 |
[운영체제] 4. 프로세스 상태와 스케쥴링 (0) | 2019.12.19 |
[운영체제] 3. 프로세스 스케쥴링 알고리즘 (0) | 2019.12.19 |
[운영체제] 2. 프로그램 처리 방법들 (0) | 2019.12.19 |
[운영체제] 1. 운영체제의 큰 그림 (0) | 2019.12.19 |