프로세스간 통신의 실제

Timo·2022년 7월 22일
0
post-thumbnail

3.7 Examples of IPC Systems

  • Shared Memory: POSIX Shared Memory
  • Message Passing: Pipes

POSIX shared memory

  • memory-mapped files 사용
  • 사용하는 명령어
    shm_open -> shared memory open
    mmap -> 메모리 매핑
    shm_fd
    shm_unlink -> delete shred memory
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <fcntl.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 
#include <sys/mman.h> 

int main() { 

	const int SIZE = 4096;const char *name = "OS";const char *message_0 = "Hello, ";const char *message_1 = "Shared Memory!\n"; 

	int shm_fd;     // the file descriptor of shared memory
	char *ptr;      // pointer to shared memory

	/* create the shared memory object */
	shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666); 

	/* configure the size of the shared memory */ 
	ftruncate(shm_fd, SIZE);

	/* map the shared memory object */
	ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); 

	/* write to the shared memory */
	sprintf(ptr, "%s", message_0); ptr += strlen(message_0); 		sprintf(ptr, "%s", message_1); ptr += strlen(message_1); 
	
	return 0; 
} 
#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 
#include <sys/mman.h> 

int main() { 
	const int SIZE = 4096;	// the size of shared memory
	const char *name = "OS"; // the name of shared memory

	int shm_fd;     // the file descriptor of shared memory
	char *ptr;      // pointer to shared memory/* create the shared memory object */
	shm_fd = shm_open(name, O_RDONLY, 0666);

	/* map the shared memory object */
	ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); 

	/* read from the shared memory object */ 
	printf("%s", (char *)ptr);
    
	/* remove the shared memory */
	shm_unlink(name);

	return 0;
} 

Pipes

  • pipe system call 사용
  • Ordinary pipes
    * parent-child 명시 필요
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

#define BUFFER_SIZE 25 
#define READ_END 0 
#define WRITE_END 1 

int main() { 
	char write_msg[BUFFER_SIZE] = "Greetings";
	char read_msg[BUFFER_SIZE];
	int fd[2];
	pid_t pid;
    
	/* create the pipe */
	pipe(fd); 

	pid = fork();  // fork a new process

	if (pid > 0) { // parent processclose(fd[READ_END]);/* write to the pipe */write(fd[WRITE_END], write_msg, strlen(write_msg) + 1); 
		close(fd[WRITE_END]); 
	}
	else if (pid == 0) { // child process
		close(fd[WRITE_END]);/* read to the pipe */read(fd[READ_END], read_msg, BUFFER_SIZE); printf("read %s\n", read_msg); 
		close(fd[READ_END]); 
	} 

	return 0; 
} 

3.8 Communication in Client-Server Systems

Sockets

  • IP addr(컴퓨터와 컴퓨터) + port(파이프와 파이프)
import java.net.*; 
import java.io.*; 

public class DateServer {
    
	public static void main(String[] args) throws Exception {
		ServerSocket server = new ServerSocket(6013); 
		/* Now listen for connections */
		while (true) {Socket client = server.accept();PrintWriter pout = new PrintWriter(client.getOutputStream(), true); 

			/* write the Date to the socket */
			pout.println(new java.util.Date().toString());

			/* close the socket and resume listening for connections */ 
			client.close();
		}
	} 
} 
import java.net.*;
import java.io.*;

public class DateClient {
	public static void main(String[] args) throws Exception {
		/* make connection to server socket */
		Socket socket = new Socket("127.0.0.1", 6013);
		InputStream in = socket.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(in)); 
          
		/* read date from the socket */
		String line = null;
		while ((line = br.readLine()) != null)
			System.out.println(line); 

		/* close the socket connections */
		socket.close();    
	}
} 

Remote Procedure Calls (RPC)

  • 원격지의 프로시져(함수) 호출
  • stub
  • skeleton
    -> stub을 통해서 skeleton을 호출한다.
  • marshals (직렬화와 비슷한 개념?)

퀴즈

  1. Two fundamental models of inter-process communication are:
    1) shared-memory and message-passing
    2) pipes and sockets
    3) sockets and remote procedure call
    4) ordinary pipes and named pipes

  2. 생산자-소비자 문제를 shared memory로 해결하는 방법에 대한 설명으로 가장 옳은 것은?
    1) 운영체제가 알아서 shared memory의 생성과 소멸을 처리해 주므로, 구현하기가 편하다.
    2) POSIX 표준에서는 shared memory를 지원하지 않는다.
    3) shared memory는 memory-mapped file로만 만들 수 있다.
    4) 생산자는 공유 버퍼에 메시지를 write()하고, 소비자는 공유 버퍼로부터 read()한다.

  3. Message-Passing 방식의 IPC에 대한 설명으로 가장 옳은 것은?
    1) message-passing 방식은 두 개의 프로세스간 통신에서만 사용할 수 있다.
    2) message를 생산자가 소비자에게 직접 전달하는 direct 통신 방식이다.
    3) 메시지의 전송이 완료될 때까지 block되는 send를 사용하면 asynchronous 통신을 할 수 있다.
    4) mailbox(또는 port)를 사용한 message-passing은 indirect 통신을 가능하게 한다.

  4. UNIX의 pipe에 대한 설명으로 가장 틀린 것은?
    1) ordinary pipe는 생산자-소비자 방식으로 두 개의 프로세스가 서로 통신하는 메커니즘이다.
    2) ordinary pipe는 한쪽 끝단에서 write를 하고, 다른쪽 끝단에서 read를 하므로 단방향 통신만 할 수 있다.
    3) ordinary pipe로 양방향 통신을 하기 위해서는 두 개의 파이프를 사용하면 된다.
    4) ordinary pipe를 사용하는 두 개의 프로세스가 반드시 부모-자식 관계일 필요는 없다.

profile
나는 매일 성장하는 사람

0개의 댓글