Skip to content
ChoYG edited this page Aug 4, 2016 · 1 revision

Inter-Process Communication(IPC)

유닉스 시스템에서 여러 쓰래드간 커뮤니케이션을 해야 하는 경우가 있다. RTOS를 사용할 때에는 주로 큐를 하나 만들어 이용했는데, 유닉스에는 다음과 같은 방법이 있다고 한다.

  • 공유자원 영역(전역변수 같은)
  • 소켓통신
  • Pipe

이중 Pipe는 두개의 파일 디스크립터를 이용해 커뮤니케이션 하는 방법이다.

pipe

pipe(파일 디스크립터 배열(길이2))

파일 디스크립터를 길이가 2인 배열로 선언한다. 파일 디스크립터를 선언할 때 다음과 같이 선언했다고 가정해보자.

int fd[2];

그 후 파일을 open 한 후에 pipe 함수를 이용했다면

pipe(fd);
  1. fd[1]로 값을 써 넣으면
  2. fd[0]으로 값을 읽을 수 있다.

pipe.c

#include <stdio.h>
#include <unistd.h>
#include <wait.h>
#include <stdlib.h>


#define BUFSIZE 8192

int main() 
{
	char inbuf[BUFSIZE];
	int p[2], j, pid;

	/* open pipe */
	if(pipe(p) == -1) 
	{
		perror("pipe call error");
		exit(1);
	}

	switch(pid = fork())
	{
	case -1: perror("error: fork failed"); 
		exit(2);
	case 0: /* if child then write down pipe */
		close(p[0]); /* first close the read end of the pipe */
		write(p[1], "Hello there.", 12);
		write(p[1], "This is a message.", 18);
		write(p[1], "How are you?", 12);
		break;
	default: /* parent reads pipe */
		close(p[1]); /* first close the write end of the pipe */
		read(p[0], inbuf, BUFSIZE); /* What is wrong here?? */
		printf("Parent read: %s\n", inbuf);
		wait(NULL);
	}

	exit(0);
}
Parent read: Hello there.This is a message.How are you?

fork 전에 pipe 함수를 사용해 커뮤니케이션용 파일 디스크립터를 지정하고, 자식 프로세스에서 데이터를 보네면 부모 프로세스에서 받는 간단한 예제다.

여기서 볼 점은, 쓰는 쪽에서는 읽기용 p[0]를 close 하고, 읽는 쪽에서는 쓰기용 p[1]을 close 한다는 것이다.
또한 중간에 주석으로

/* What is wrong here?? */

이라는 문구가 있는데, 이런 상황에서 과연 read 함수가 안정적으로 동작할까? 라는 의문을 던지는 것 같다. 실제로 위 예제는 내 PC 에서 정상적으로 동작하였다. 하지만 이건 쓰기 속도가 빨랐기 때문에 읽기 전에 운이 좋게 다 쓰여졌던게 아닐까 생각한다. 내가 생각해본 해결방법은 이렇다.

  • while 문으로 읽기 동작을 수행한다.
  • 읽기 동작은 rio_readlineb 등을 이용한다. 보낼때 '\n' 문자를 추가하면 될 것이다.
  • 또는 별도의 특수한 문자를 이용해 "데이터의 끝"을 알리는 방법을 이용하면 되지 않을까.

시리얼 통신시에는 별도로 프로토콜을 간단하게 구성해서 해결했는데, 이런식으로 접근하는것도 나름 쓸만한 것 같다.

Clone this wiki locally