Chapter 7. Pipe

34
Chapter 7. Pipe Chapter 7. Pipe http://network.hanbat.ac.kr

description

Chapter 7. Pipe. http://network.hanbat.ac.kr. pipe 개요. Simple IPC (inter process communication) mechanism 두 프로세스간 통신 기능 제공 동작 방식 수도관 (pipe) 을 통해서 흐르는 물 ( 데이터 ) 과 유사 Writing process 와 Reading process 사이에 동기화를 제공 Writing process 가 아직 write 를 하지 않은 파이프에서 read 하는 경우 read(2) 가 block - PowerPoint PPT Presentation

Transcript of Chapter 7. Pipe

Page 1: Chapter 7. Pipe

Chapter 7. PipeChapter 7. Pipe

http://network.hanbat.ac.kr

Page 2: Chapter 7. Pipe

2

pipe pipe 개요개요 Simple IPC (inter process communication) mechanism

두 프로세스간 통신 기능 제공 동작 방식

수도관 (pipe) 을 통해서 흐르는 물 ( 데이터 ) 과 유사

Writing process 와 Reading process 사이에 동기화를 제공 Writing process 가 아직 write 를 하지 않은 파이프에서 read 하는 경우

read(2) 가 block Reading process 가 읽지 않고 , writing process 가 계속 write 하여

파이프가 가득 찬 경우 write(2) 가 block

write file descriptor

read file descriptor

pipe

Page 3: Chapter 7. Pipe

3

pipe(2)pipe(2)

#include <unistd.h>

int pipe (int filedes[2]);

pipe 의 생성 수행결과

filedes[0] 파이프에서 읽기 위한 file descriptor 값이 저장됨

filedes[1] 파이프에 쓰기를 위한 file descriptor 값이 저장됨

Return Success : 0 Failure : -1 and erron is set

Page 4: Chapter 7. Pipe

4

pipe(2): pipe(2): 수행 결과수행 결과

int fd[2];pipe(fd); 의 수행 결과

...fd[0]

...fd[1]

file descriptor table

r

w

file table inode table

...readfd[0]

...writefd[1]

file descriptor table

Page 5: Chapter 7. Pipe

5

pipe(2) pipe(2) 적용 가능한 시스템 호출들적용 가능한 시스템 호출들 open(2)

사용 안됨 close(2)

파이프로의 접근이 완료되었을 때 사용 read(2)

파이프가 비어있다면 멈춤 (block) write(2)

파이프가 꽉 차있다면 멈춤 (block) lseek(2)

사용 안됨 dup(2)

파이프로의 입출력 방향을 변경 (redirection) 을 위해 사용됨 fcntl(2)

입출력시 지연이 없도록 함

Page 6: Chapter 7. Pipe

6

pipe(2): Examplespipe(2): Examples

...rfd[0]...wfd[1]

file descriptor table

r

w

file table inode table

...rfd[0]...wfd[1]

PARENT

CHILD

Page 7: Chapter 7. Pipe

7

#include<stdio.h>#define MSGSIZE 20main (int argc, char *argv[]) {

int fd[2], pid;char msgin[MSGSIZE], msgout[MSGSIZE] = "\nHello, world\n";if (pipe(fd) == -1) {

perror(argv[0]); exit(1);}if ((pid = fork()) > 0) { /* parent */

write (fd[1], msgout, MSGSIZE);}else if (pid == 0) { /* child */

read (fd[0], msgin, MSGSIZE);puts (msgin);

}}

Page 8: Chapter 7. Pipe

8

% gcc q.c% a.out%Hello, world

%

Page 9: Chapter 7. Pipe

9

who.c: who.c: 전체 동작전체 동작

...rfd[0]...wfd[1]

file descriptor table

r

w

file table inode tablePARENT [0]

[1][2]

stdinstdoutstderr

...rfd[0]...wfd[1]

Child 1[0][1][2]

printf (“who display ... execl(/usr/bin/who

...rfd[0]...wfd[1]

Child 2[0][1][2]

stdoutstderr

read2line execl(/bin/sort

close(1), dup(fd[1]) close(fd[0]), close(fd[1])

close(0), dup(fd[0]) close(fd[0]), close(fd[1])

Page 10: Chapter 7. Pipe

10

who.cwho.c#include <stdio.h>char text[80];main (int argc, char **argv){

int fd[2];if (pipe(fd) == -1) {

perror(argv[0]); exit(1);}if (fork() == 0) { /* first child */

close (1);dup (fd[1]); /* redirect std output */close (fd[0]); close (fd[1]);printf ("who display sorted\n"); fflush (stdout);execl ("/usr/bin/who", "who", (char*) 0);exit (127);

}

Page 11: Chapter 7. Pipe

11

who.c: who.c: 현재 상태현재 상태

...rfd[0]...wfd[1]

file descriptor table

r

w

file table inode tablePARENT [0]

[1][2]

stdinstdoutstderr

...rfd[0]...wfd[1]

Child 1[0][1][2]

printf /usr/bin/who

Page 12: Chapter 7. Pipe

12

who.c: who.c: 계속계속

if (fork() == 0) { /* second child */close (0);dup (fd[0]); /* redirect std input */close (fd[0]); close (fd[1]);read2line (text);printf ("\tHeading: %s\n", text); fflush (stdout);/* sort 는 stdin 입력 , stdout 출력 */execl ("/bin/sort", "sort", (char*) 0); exit (127);

} close (fd[0]); close (fd[1]); while (wait((char*)0) != -1)

; exit(0);}

read2line(char *input){ while (1) { read (0, input, 1); if (*input == '\n') break; else input++; }}

Page 13: Chapter 7. Pipe

13

% a.out Heading: who display sorted

dksung pts/5 5 월 17 09:03 (202.30.46.39)egkim pts/9 5 월 18 17:27 (203.230.107.166)root console 4 월 7 11:23 (:0)root pts/3 4 월 7 11:23 (:0.0)root pts/8 5 월 17 10:43 (:0.0)%

Page 14: Chapter 7. Pipe

14

create_pipe1.c: create_pipe1.c: 전체 동작전체 동작

...rsend_ fd[0]w

file descriptor table

rw

file table inode tablePARENT [0]

[1][2]

stdinstdoutstderr

send_ fd[1]rrcv_ fd[0]wrcv_ fd[1]

rw

...rsend_ fd[0]w

Child [0][1][2]

stdinstdoutstderr

send_ fd[1]rrcv_ fd[0]wrcv_ fd[1]

read(send_ fd[0],write(rcv_ fd[1],

read(0,write(send_ fd[1],read(rcv_ fd[0],

Page 15: Chapter 7. Pipe

15

% a.outthis is test...[Parent] : Send Message : this is test...

[Child] : Receive Message : this is test...

[Child] : Send Message : this is test...

[Parent] : Receive Message : this is test...

%

Page 16: Chapter 7. Pipe

16

create_pipe1.c: create_pipe1.c: 학생들이 직접 읽고 해석학생들이 직접 읽고 해석 ..

#include <stdio.h>#include <unistd.h>#include <errno.h>#define MAX_SIZE 50main() { int send_fd[2], rcv_fd[2], pid=0, size=0; char send_buf[MAX_SIZE], rcv_buf[MAX_SIZE]; memset (send_buf, 0x00, MAX_SIZE); memset (rcv_buf, 0x00, MAX_SIZE); if ( pipe(send_fd) == -1 ) { perror("pipe() : "); exit(1); } if ( pipe(rcv_fd) == -1 ) { perror("pipe() : "); exit(2); }

Page 17: Chapter 7. Pipe

17

if ((pid = fork()) == 0 ) { /* Child */close(send_fd[1]); close(rcv_fd[0]);size = read(send_fd[0], rcv_buf, MAX_SIZE);printf("\t[Child] : Receive Message : %s\n", rcv_buf);write(rcv_fd[1], rcv_buf, size);printf("\t[Child] : Send Message : %s\n", rcv_buf);exit(0);

}else if ( pid > 0 ) { /* Parent */

close(send_fd[0]); close(rcv_fd[1]);size = read(0, send_buf, MAX_SIZE);write(send_fd[1], send_buf, size);printf("[Parent] : Send Message : %s\n", send_buf);read(rcv_fd[0], rcv_buf, MAX_SIZE);printf("[Parent] : Receive Message : %s\n", rcv_buf);

}}

Page 18: Chapter 7. Pipe

18

create_pipe2.c: create_pipe2.c: 전체 동작전체 동작

...rfd[0]...wfd[1]

file descriptor table

r

w

file table inode tablePARENT [0]

[1][2]

stdinstdoutstderr

...rfd[0]...wfd[1]

Child 1[0][1][2]

read(0, buf, execlp(buf,

...rfd[0]...wfd[1]

Child 2[0][1][2] printf (“%s”, argv[1]

stdoutstderr

Page 19: Chapter 7. Pipe

19

create_pipe2.ccreate_pipe2.c

#include <stdio.h>#include <unistd.h>#include <errno.h>#define MAX_SIZE 50main (int argc, char *argv[]) { int fd[2], pid=0, size=0, status=0;

char buf[MAX_SIZE];memset (buf, 0x00, MAX_SIZE);if ( pipe(fd) == -1 ) {

perror("pipe() : "); exit(1);}if ( fork() == 0 ) {

close(0); dup(fd[0]);close(fd[0]); close(fd[1]);size = read(0, buf, MAX_SIZE);execlp(buf, buf, (char *)NULL);perror("execlp() : "); exit(3);

}

Page 20: Chapter 7. Pipe

20

if ( fork() == 0 ) {close (1); dup (fd[1]);close (fd[0]); close (fd[1]);printf ("%s", argv[1]);fflush (stdout);exit(0);

}close (fd[0]); close(fd[1]);while ( wait(&status) != -1 )

;exit(0);

}

Page 21: Chapter 7. Pipe

21

% a.out date2004. 05. 19. ( 수 ) 11:28:16 KST%

Page 22: Chapter 7. Pipe

22

실습실습 7 page 10 ~ 12 page 16 ~ 17 page

학생들이 직접 읽고 해석한 이후에 실습 유사한 시험 문제 나올 수 있음 .

19 ~ 20 page

Page 23: Chapter 7. Pipe

23

Pipe Pipe 표준 라이브러리표준 라이브러리

생략

Page 24: Chapter 7. Pipe

24

mknod(1)mknod(1) Create a special file

Block special file /dev/hda: hard-diskbbrw-rw---- 1 root disk 3, 0 Mar 24 2001 /dev/hda

Character special file /dev/ttyccrw-rw-rw- 1 root root 5, 0 Mar 24 2001 /dev/tty

FIFO Named pipe 를 위한 파일pprw-rw-r-- 1 egkim egkim 0 Mar 19 19:17 pipeFile

Named pipe 를 위한 special file 의 생성% mknod pipeFile p%

Page 25: Chapter 7. Pipe

25

mknod(1)mknod(1) 의 사용 예의 사용 예 : Shell: Shell

% cat data1 abcdefghijklmnopqrstuvwxyz2 abcdefghijklmnopqrstuvwxyz3 abcdefghijklmnopqrstuvwxyz%% lsdata% mknod NP p% lsNP data% cat NP

blocking until data received1 abcdefghijklmnopqrstuvwxyz2 abcdefghijklmnopqrstuvwxyz3 abcdefghijklmnopqrstuvwxyz%

%% cat data > NP

send data to NP%

Page 26: Chapter 7. Pipe

26

mknod(3): mknod(3):

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>

int mknod (const char *pathname, mode_t mode, dev_t dev);

Create a directory or special or ordinary file Parameter

pathname: 경로를 포함하는 파일 이름 mode: 생성하려는 파일의 permission 및 type (“|” 로 조합 )

Type S_IFREGS_IFREG ( 일반 파일 ), S_IFCHRS_IFCHR (character special file), S_IFBLKS_IFBLK (block special file), S_IFIFOS_IFIFO

(named pipe) 예 : mknod (“pipeFile ”, S_IFIFO | 0660, 0);

dev: FIFO 용 으로는 사용하지 않음 Return

Success : 0 Failure : -1 and errno is set

Page 27: Chapter 7. Pipe

27

Named pipeNamed pipe 에 적용 가능한 시스템 호출들에 적용 가능한 시스템 호출들 open(2)

정규 파일에서와 동일하게 사용 clos(2)

Named pipe 로의 접근이 완료되었을 때 사용 read(2)

일반적으로 데이터가 없으면 멈춤 (block) write(2)

일반적으로 파이프에 데이터가 꽉 차면 멈춤 (block) lseek(2)

사용하지 않음 dup(2)

파이프로 입출력 방향을 변경 (redirection) 을 위해 사용됨 fcntl(2)

입출력을 위한 지연이 없도록 set 할 때 사용

Page 28: Chapter 7. Pipe

28

Named Pipe Example: Client-Server modeNamed Pipe Example: Client-Server mode

Client File Server

public named pipe (Public)(file name, pipe name)

private named pipe (Fifo456)(file data)

Fileargv[1]:

파일 이름

Page 29: Chapter 7. Pipe

29

Client – Server ProgramClient – Server Program namedPipe.h

struct message { char privfifo[15]; /* name of private named pipe */ char filename[100]; /* name of file */};#define PUBLIC "Public"#define LINESIZE 512#define NUMTRIES 3

Page 30: Chapter 7. Pipe

30

file_server.cfile_server.c#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include "namedPipe.h"main (int argc, char *argv[]) { int fdpub, fdpriv, fd, n, i; struct message msg; char line[LINESIZE];

/* mknod(1) 을 이용하여 , FIFO special file 을 만들지 않았으면 생성 */ /* 이미 만들어져 있으면 , mknod(2) 에러 발생 무시 */ mknod (PUBLIC, S_IFIFO|0666, 0);

if ((fdpub = open(PUBLIC, O_RDONLY)) == -1) {perror(PUBLIC); exit(1);

}

Page 31: Chapter 7. Pipe

31

loop: /* forever */while (read(fdpub, (char *) &msg, sizeof(msg)) >0) {

printf (“Client Request Arrived.\n”);if ((fd=open(msg.filename, O_RDONLY)) == -1) {

perror(msg.filename); break;}for (i= 0; i< NUMTRIES; i++)

if ((fdpriv = open(msg.privfifo, O_WRONLY|O_NDELAY)) == -1) sleep(1);

else break;if (fdpriv == -1) {

perror (msg.privfifo); break;}while ((n=read(fd, line, LINESIZE)) > 0)

write (fdpriv, line, n);close (fd); close (fdpriv);

}goto loop;

}

Page 32: Chapter 7. Pipe

32

client.cclient.c

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include "namedPipe.h"main (int argc, char *argv[]) { struct message msg; int n, fdpub, fdpriv; char line[LINESIZE];

sprintf (msg.privfifo, "Fifo%d", getpid());

if (mknod(msg.privfifo, S_IFIFO| 0666, 0) == -1) { perror(msg.privfifo); exit(1); }

Page 33: Chapter 7. Pipe

33

if ((fdpub = open(PUBLIC, O_WRONLY)) == -1) {perror (PUBLIC); exit(2);

}strcpy (msg.filename, argv[1]);write (fdpub, (char *) &msg, sizeof(msg));if ((fdpriv = open(msg.privfifo, O_RDONLY)) ==-1) {

perror (msg.privfifo); exit(3);}while ((n=read(fdpriv, line, LINESIZE)) > 0)

write(1,line,n);close (fdpriv);unlink (msg.privfifo);exit(0);

}

Page 34: Chapter 7. Pipe

34

% gcc -o server server.c% gcc -o client client.c%% serverClient Request Arrived.

% cat data1 abcdefghijklmnopqrstuvwxyz2 abcdefghijklmnopqrstuvwxyz3 abcdefghijklmnopqrstuvwxyz%% client data1 abcdefghijklmnopqrstuvwxyz2 abcdefghijklmnopqrstuvwxyz3 abcdefghijklmnopqrstuvwxyz%