1 / 34

Chapter 7. Pipe

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

enya
Download Presentation

Chapter 7. Pipe

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. 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

  3. 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): 수행 결과

  5. pipe(2) 적용 가능한 시스템 호출들 • open(2) • 사용 안됨 • close(2) • 파이프로의 접근이 완료되었을 때 사용 • read(2) • 파이프가 비어있다면 멈춤(block) • write(2) • 파이프가 꽉 차있다면 멈춤(block) • lseek(2) • 사용 안됨 • dup(2) • 파이프로의 입출력 방향을 변경(redirection)을 위해 사용됨 • fcntl(2) • 입출력시 지연이 없도록 함

  6. pipe(2): Examples

  7. #include<stdio.h> #define MSGSIZE 20 main (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: 전체 동작

  10. who.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: 현재 상태

  12. 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: 전체 동작

  15. % a.out this 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: 학생들이 직접 읽고 해석. #include <stdio.h> #include <unistd.h> #include <errno.h> #define MAX_SIZE 50 main() { 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: 전체 동작

  19. create_pipe2.c #include <stdio.h> #include <unistd.h> #include <errno.h> #define MAX_SIZE 50 main (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 date 2004. 05. 19. (수) 11:28:16 KST %

  22. 실습 • 7 page • 10 ~ 12 page • 16 ~ 17 page • 학생들이 직접 읽고 해석한 이후에 실습 • 유사한 시험 문제 나올 수 있음. • 19 ~ 20 page

  23. Pipe 표준 라이브러리 • 생략

  24. mknod(1) • Create a special file • Block special file • /dev/hda: hard-disk brw-rw---- 1 root disk 3, 0 Mar 24 2001 /dev/hda • Character special file • /dev/tty crw-rw-rw- 1 root root 5, 0 Mar 24 2001 /dev/tty • FIFO • Named pipe를 위한 파일 prw-rw-r-- 1 egkim egkim 0 Mar 19 19:17 pipeFile • Named pipe를 위한 special file의 생성 % mknod pipeFile p %

  25. % cat data 1 abcdefghijklmnopqrstuvwxyz 2 abcdefghijklmnopqrstuvwxyz 3 abcdefghijklmnopqrstuvwxyz % % ls data % mknod NP p % ls NP data % cat NP blocking until data received 1 abcdefghijklmnopqrstuvwxyz 2 abcdefghijklmnopqrstuvwxyz 3 abcdefghijklmnopqrstuvwxyz % % % cat data > NP send data to NP % mknod(1)의 사용 예: Shell

  26. 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_IFREG (일반 파일), S_IFCHR (character special file), S_IFBLK (block special file), S_IFIFO (named pipe) • 예: mknod (“pipeFile ”, S_IFIFO | 0660, 0); • dev: FIFO용 으로는 사용하지 않음 • Return • Success : 0 • Failure : -1 and errno is set

  27. Named 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 mode

  29. Client – 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.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.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 % % server Client Request Arrived. % cat data 1 abcdefghijklmnopqrstuvwxyz 2 abcdefghijklmnopqrstuvwxyz 3 abcdefghijklmnopqrstuvwxyz % % client data 1 abcdefghijklmnopqrstuvwxyz 2 abcdefghijklmnopqrstuvwxyz 3 abcdefghijklmnopqrstuvwxyz %

More Related