상세 컨텐츠

본문 제목

3. Process - RPC / Pipes

Operating System

by seoia 2020. 4. 22. 20:18

본문

Remote Procedure Calls (RPC)

 

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으로 만들어서 전송한다.

 

 

  • Marshal / Unmarshal

Marshal / Unmarshal

Marshalling : packaging (native format -> standard format)

Unmarshalling : Unpackaging (standard format -> native format)

 

 

 


 

 

Pipes

 

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);   //아예 프로세스를 종료한다.
}

'Operating System' 카테고리의 다른 글

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

관련글 더보기