Chapter 7. Pipe
description
Transcript of Chapter 7. Pipe
Chapter 7. PipeChapter 7. Pipe
http://network.hanbat.ac.kr
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
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
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
5
pipe(2) pipe(2) 적용 가능한 시스템 호출들적용 가능한 시스템 호출들 open(2)
사용 안됨 close(2)
파이프로의 접근이 완료되었을 때 사용 read(2)
파이프가 비어있다면 멈춤 (block) write(2)
파이프가 꽉 차있다면 멈춤 (block) lseek(2)
사용 안됨 dup(2)
파이프로의 입출력 방향을 변경 (redirection) 을 위해 사용됨 fcntl(2)
입출력시 지연이 없도록 함
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
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);
}}
8
% gcc q.c% a.out%Hello, world
%
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])
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);
}
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
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++; }}
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)%
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],
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...
%
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); }
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);
}}
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
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);
}
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);
}
21
% a.out date2004. 05. 19. ( 수 ) 11:28:16 KST%
22
실습실습 7 page 10 ~ 12 page 16 ~ 17 page
학생들이 직접 읽고 해석한 이후에 실습 유사한 시험 문제 나올 수 있음 .
19 ~ 20 page
23
Pipe 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%
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%
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
27
Named pipeNamed pipe 에 적용 가능한 시스템 호출들에 적용 가능한 시스템 호출들 open(2)
정규 파일에서와 동일하게 사용 clos(2)
Named pipe 로의 접근이 완료되었을 때 사용 read(2)
일반적으로 데이터가 없으면 멈춤 (block) write(2)
일반적으로 파이프에 데이터가 꽉 차면 멈춤 (block) lseek(2)
사용하지 않음 dup(2)
파이프로 입출력 방향을 변경 (redirection) 을 위해 사용됨 fcntl(2)
입출력을 위한 지연이 없도록 set 할 때 사용
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]:
파일 이름
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
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);
}
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;
}
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); }
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);
}
34
% gcc -o server server.c% gcc -o client client.c%% serverClient Request Arrived.
% cat data1 abcdefghijklmnopqrstuvwxyz2 abcdefghijklmnopqrstuvwxyz3 abcdefghijklmnopqrstuvwxyz%% client data1 abcdefghijklmnopqrstuvwxyz2 abcdefghijklmnopqrstuvwxyz3 abcdefghijklmnopqrstuvwxyz%