-
Notifications
You must be signed in to change notification settings - Fork 1
pipe
ChoYG edited this page Aug 4, 2016
·
1 revision
유닉스 시스템에서 여러 쓰래드간 커뮤니케이션을 해야 하는 경우가 있다. RTOS를 사용할 때에는 주로 큐를 하나 만들어 이용했는데, 유닉스에는 다음과 같은 방법이 있다고 한다.
- 공유자원 영역(전역변수 같은)
- 소켓통신
- Pipe
이중 Pipe는 두개의 파일 디스크립터를 이용해 커뮤니케이션 하는 방법이다.
pipe(파일 디스크립터 배열(길이2))파일 디스크립터를 길이가 2인 배열로 선언한다. 파일 디스크립터를 선언할 때 다음과 같이 선언했다고 가정해보자.
int fd[2];그 후 파일을 open 한 후에 pipe 함수를 이용했다면
pipe(fd);- fd[1]로 값을 써 넣으면
- fd[0]으로 값을 읽을 수 있다.
#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' 문자를 추가하면 될 것이다.
- 또는 별도의 특수한 문자를 이용해 "데이터의 끝"을 알리는 방법을 이용하면 되지 않을까.
시리얼 통신시에는 별도로 프로토콜을 간단하게 구성해서 해결했는데, 이런식으로 접근하는것도 나름 쓸만한 것 같다.