RPC는 프로세스와 프로세스가 네트워크로 이어져있을 때 발생하는 호출이다. (client와 server간의 함수 호출)
network로 request를 주고 받는다.
원격 function call을 하게 해주는 program module이다.
RPC는 stubs라는 조그만 프로그램을 통해 제공된다.
Stubs는 원격에서 더 큰 프로그램 또는 remote side의 서비스에 인터페이스를 제공하는 작은 프로그램으로,
- Client stub / server stub => 양쪽에서 각각의 임무를 수행한다.
- Locate port on server => 서버의 포트를 찾아낸다.
- Marshal / Unmarshal 파라미터 => operation을 수행한다.
서버와 클라이언트가 통신할 때 IP주소와 포트를 tapping해서 stub으로 만들어서 전송한다.
Marshalling : packaging (native format -> standard format)
Unmarshalling : Unpackaging (standard format -> native format)
Pipes는 부모-자식 프로세스 통신할 때 사용한다.
프로세스 사이에 파이프를 두고 정보를 주고 받는 일종의 가상통로이다.
파이프는 단방향이다. -> 정보를 주고받으려면 파이프가 두개 필요하다.
파이프 자체는 fork 함수에 의해 복사되지 않는다.
파이프가 필요한 이유?
각 프로세스에는 해당하는 메모리가 독립적으로 존재하여 메모리로 통신하는 것이 불가능하다.
fork() 로 자식 프로세스가 생성되더라도 데이터를 주고 받을 방법이 없다.
때문에 pipes를 통해 서로 다른 프로세스가 데이터를 주고 받을 수 있다.
- Ordinary pipes
단방향 커뮤니케이션.
부모 자식간에 커뮤니케이션 할 때 사용한다.
- Named pipes
좀 더 일반적이고 많은 기능을 한다.
꼭 부모-자식 관계가 아니더라도 통신이 가능하다.
Pipe 예제 프로그래밍
(출처 : https://zoomkoding.github.io/os/linux/2019/04/07/os-pipe.html )
pipe (int fd[2]);
- pipe는 크기가 2인 int형 배열을 요구한다.
- fd[0] : 함수 호출 후 fd[0]에 입력 받을 수 있는 파일 디스크립터가 담긴다.
읽을 때 fd[0]을 통해서 읽는다.
- fd[1] : 함수 호출 후 데이터를 출력할 수 있는 파일 디스크립터가 담긴다.
쓰는 내용은 fd[1]에다가 적는다.
main()
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
int pipes[2];
int main() {
pid_t child_pid;
int exit_code;
if(pipe(pipes) !=0){
perror("Error");
exit(1);
}
printf("%d %d \n", pipes[0], pipes[1]);
child_pid = fork();
if(child_pid == 0)
child_proc();
else
parent_proc();
wait($exit_code);
exit(0);
}
부모 프로세스 실행 코드이다.
void parent_proc(){
char * buf=0x0;
sszie_t s;
size_t len=0;
close(pipes[0]); //부모 프로세스에서는 읽지 않을 것이므로 읽기용 파이프를 닫는다.
while((s=getline(&buf, &len, stdin)) != -1) { //getline을 통해 input을 읽는다.
buf[s-1] = 0x0;
ssize_t sent=0;
char * data = buf;
while(sent<s){
sent += write(pipes[1], buf+sent, s-sent) ; //pipes[1]을 통해서 쓰기를 진행한다.
}
free(buf);
buf=0x0;
len=0;
}
close(pipes[1]); // 쓰기용 파이프를 닫는다.
}
자식 프로세스 실행 코드이다.
//파이프로 전달된 내용을 프린트한다.
void child_proc() {
char buf[32];
ssize_t s;
close(pipes[1]); //쓰기용 파이프를 닫아준다.
while((s = read(pipes[0], buf, 31)) > 0) { //파이프의 내용을 읽어들인다.
buf[s+1] = 0x0 ;
printf("> %s\n", buf);
}
exit(0); //아예 프로세스를 종료한다.
}
6. Process Synchronization_2 (0) | 2020.05.05 |
---|---|
6. Process Synchronization _ 1 , Peterson's Solution (0) | 2020.04.22 |
3. Process - Socket (0) | 2020.04.22 |