Microsoft PowerPoint - 09-Pipe

Similar documents
슬라이드 1

제1장 Unix란 무엇인가?

Microsoft PowerPoint - ch09_파이프 [호환 모드]

2009년 상반기 사업계획

6주차.key

슬라이드 1

10.

ABC 11장

1장. 유닉스 시스템 프로그래밍 개요

좀비프로세스 2

제1장 Unix란 무엇인가?

1장. 유닉스 시스템 프로그래밍 개요

/chroot/lib/ /chroot/etc/

제12장 파일 입출력

<4D F736F F F696E74202D FC7C1B7CEBCBCBDBA20BBFDBCBAB0FA20BDC7C7E0205BC8A3C8AF20B8F0B5E55D>

2009년 상반기 사업계획

제9장 프로세스 제어

슬라이드 1

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

PowerPoint 프레젠테이션

The Pocket Guide to TCP/IP Sockets: C Version

chap7.key

K&R2 Reference Manual 번역본

Microsoft PowerPoint APUE(File InO).pptx

2009년 상반기 사업계획

Microsoft PowerPoint APUE(File InO)

Microsoft PowerPoint - Lecture_Note_7.ppt [Compatibility Mode]

Microsoft PowerPoint APUE(File InO).ppt

untitled

Microsoft PowerPoint - chap12 [호환 모드]

vi 사용법

歯9장.PDF

PowerPoint 프레젠테이션

<4D F736F F F696E74202D BDC3B1D7B3CEB0FA20BDC3B1D7B3CE20C3B3B8AE2E707074>

PowerPoint 프레젠테이션

<4D F736F F F696E74202D FB8DEB8F0B8AE20B8C5C7CE205BC8A3C8AF20B8F0B5E55D>

2009년 상반기 사업계획

The OSI Model

제1장 Unix란 무엇인가?

Chapter #01 Subject

PowerPoint 프레젠테이션

untitled

PowerPoint 프레젠테이션

3. 다음장에나오는 sigprocmask 함수의설명을참고하여다음프로그램의출력물과그출력물이화면이표시되는시점을예측하세요. ( 힌트 : 각줄이표시되는시점은다음 4 가지중하나. (1) 프로그램수행직후, (2) kill 명령실행직후, (3) 15 #include <signal.

Microsoft Word - Network Programming_NewVersion_01_.docx

Microsoft PowerPoint - 10_Process

System Programming Lab

Microsoft PowerPoint - 10_Signal

로봇SW교육원 강의자료

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

교육지원 IT시스템 선진화

Microsoft PowerPoint - SP6장-시그널.ppt [호환 모드]

PowerPoint 프레젠테이션

À©µµ³×Æ®¿÷ÇÁ·Î±×·¡¹Ö4Àå_ÃÖÁ¾

(Asynchronous Mode) ( 1, 5~8, 1~2) & (Parity) 1 ; * S erial Port (BIOS INT 14H) - 1 -

본 강의에 들어가기 전

PowerPoint 프레젠테이션

Chap04(Signals and Sessions).PDF

고급 IPC 설비

03장.스택.key

로봇SW교육원 강의자료


PowerPoint 프레젠테이션

제1장 Unix란 무엇인가?

UniStore

untitled

Microsoft PowerPoint - chap9 [호환 모드]

chap12(process).hwp

<C1A63130C0E5C7C1B7CEBCBCBDBA2E687770>

KEY 디바이스 드라이버

Microsoft PowerPoint - chap2

3. 다음장에나오는 sigprocmask 함수의설명을참고하여다음프로그램의출력물과그출력물이화면이표시되는시점을예측하세요. ( 힌트 : 각줄이표시되는시점은다음 6 가지중하나. (1) 프로그램수행직후, (2) 5 초후 (3) 10 초후 (4) 15 #include <signa

Microsoft PowerPoint - lab14.pptx

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

고급 IPC 설비

5. 소켓 프로그래밍

13주-14주proc.PDF

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

Chap06(Interprocess Communication).PDF

untitled

4. What will be the output of this program? Explain results for each variable and each thread. #include "apue.h" int var=1; pthread_mutex_t lock; void

학번 : 이름 1. 다음프로그램실행결과를예측하시오. $./a.out & [1] 7216 $ kill -USR $ kill -USR 아래학생이작성한쓰레드코드의문제점을설명하시오. void* thread_main() { pthread_mutex_t

PowerPoint 프레젠테이션

프로그램을 학교 등지에서 조금이라도 배운 사람들을 위한 프로그래밍 노트 입니다. 저 역시 그 사람들 중 하나 입니다. 중고등학교 시절 학교 도서관, 새로 생긴 시립 도서관 등을 다니며 책을 보 고 정리하며 어느정도 독학으르 공부하긴 했지만, 자주 안하다 보면 금방 잊어

5.스택(강의자료).key

C프로-3장c03逞풚

메시지큐를이용한 IPC 프로그램구현과제보고서 1. 과제의목적 1 리눅스가지원하는프로세스간통신방식중다수의프로세스사이에구조화된데이터블럭, 즉메시지를전달하는데주로사용되는메시지큐방식에대하여무엇인지, 어떻게사용하는지공부한다. 2 공부한내용을점검하기위해기작성된 epda 프로세스관

슬라이드 1

Microsoft PowerPoint - chap05-제어문.pptx

UI TASK & KEY EVENT

BMP 파일 처리

Chapter_06

untitled

Sena Technologies, Inc. HelloDevice Super 1.1.0

untitled

Microsoft PowerPoint - [2009] 02.pptx

컴파일러

OCW_C언어 기초

The Pocket Guide to TCP/IP Sockets: C Version

PowerPoint 프레젠테이션

Transcription:

9. 파이프 상명대학교소프트웨어학부

파이프 시그널은이상한사건이나오류를처리하는데는이용하지만, 한프로세스로부터다른프로세스로대량의정보를전송하는데는부적합하다. 파이프 한프로세스를다른관련된프로세스에연결시켜주는단방향의통신채널 2

pipe() Usage #include <unistd.h> int pipe(int filedes[2]); 3

< ex_1.c > #include <unistd.h> #include <stdio.h> #define MSGSIZE 16 char *msg1 = "hello, world #1"; char *msg2 = "hello, world #2"; char *msg3 = "hello, world #3"; main() { char inbuf[msgsize]; int p[2], j; /* 파이프를개방한다 */ if(pipe(p) == -1) { perror("pipe call"); exit(1); 4

< ex_1.c > /* 파이프에쓴다 */ write(p[1], msg1, MSGSIZE); write(p[1], msg2, MSGSIZE); write(p[1], msg3, MSGSIZE); /* 파이프로부터읽는다. */ for(j = 0; j < 3; j++) { read (p[0], inbuf, MSGSIZE); printf ("%s\n", inbuf); exit (0); 5

pipe() process write( ) p[1] read( ) p[0] < 첫번째파이프사용예 > 6

< ex_2.c > #include <unistd.h> #include <stdio.h> #include <sys/types.h> #define MSGSIZE 16 char *msg1 = "hello, world #1"; char *msg2 = "hello, world #2"; char *msg3 = "hello, world #3"; main() { char inbuf[msgsize]; int p[2], j; pid_t pid; /* 파이프를개방한다. */ if (pipe (p) == -1) { perror ("pipe call"); exit (1); 7

< ex_2.c > switch (pid = fork()){ case -1: perror ("fork call"); exit (2); case 0: write (p[1], msg1, MSGSIZE); write (p[1], msg2, MSGSIZE); write (p[1], msg3, MSGSIZE); break; default: for (j = 0; j < 3; j++) { read (p[0], inbuf, MSGSIZE); printf ("%s\n", inbuf); wait (NULL); exit (0); 8

pipe() child parent write( ) p[1] p[1] write( )) read( ) p[0] p[0] read( )) < 두번째파이프사용예 > 9

< ex_3.c > #include <unistd.h> #include <stdio.h> #include <sys/types.h> #define MSGSIZE 16 char *msg1 = "hello, world #1"; char *msg2 = "hello, world #2"; char *msg3 = "hello, world #3"; main() { char inbuf[msgsize]; int p[2], j; pid_t pid; /* 파이프를개방한다. */ if (pipe(p) == -1) { perror ("pipe call"); exit (1); 10

< ex_3.c > switch (pid = fork()){ case -1: perror ("fork call"); exit (2); case 0: close (p[0]); write (p[1], msg1, MSGSIZE); write (p[1], msg2, MSGSIZE); write (p[1], msg3, MSGSIZE); break; default: close (p[1]); for (j = 0; j < 3; j++) { read (p[0], inbuf, MSGSIZE); printf ("%s\n", inbuf); wait (NULL); exit (0); 11

pipe() child parent p[0] write( read( ) write( ) p[1] read( ) < 세번째파이프사용예 > 12

파이프의크기 파이프에들어있는자료가일정량을초과하면, 그후의 write 는봉쇄된다. 파이프의용량을초과할가능성이있는 write 가시도되면프로세스는다른프로세스에의하여자료가읽혀져파이프에충분한공간이마련될때까지수행이일시중단된다. 13

< ex_4.c > #include <signal.h> #include <unistd.h> #include <limits.h> int count; void alrm_action(int); main() { int p[2]; int pipe_size; char c = 'x'; static struct sigaction act; act.sa_handler = alrm_action; sigfillset (&(act.sa_mask)); /* 파이프를생성한다 */ if (pipe(p) == -1) { perror ("pipe call"); exit (1); 14

< ex_4.c > /* 파이프의크기를결정한다. */ pipe_size = fpathconf (p[0], _PC_PIPE_BUF); printf ("Maximum size of write to pipe: %d bytes\n", pipe_size); sigaction (SIGALRM, &act, NULL); while (1) { alarm (20); write(p[1], &c, 1); alarm(0); if ((++count % 1024) == 0) printf ("%d characters in pipe\n", count); void alrm_action (int signo){ printf ("write blocked after %d characters\n", count); exit (0); 15

파이프닫기 쓰기전용파일기술자를닫았을때 : 자료를쓰기위해해당파이프를개방한다른프로세스가존재하는경우에는아무일도일어나지않는다. 파이프에자료를쓰는프로세스가더이상없고, 파이프가비어있으면, 그파이프로부터자료를읽으려는프로세스는아무자료도읽을수가없다. 파이프로부터자료를읽기를기다리며잠들어있던프로세스를모두깨우고, 이들의 read() 호출은 0을반환한다. 따라서자료를읽는프로세스에게는보통파일의끝에도달한것과같은효과가발생한다. 16

파이프닫기 읽기전용파일기술자를닫았을때 : 자료를읽기위해해당파이프를개방한프로세스가아직남아있는경우에는아무일도발생하지않는다. 파이프로부터자료를읽어들이는프로세스가더이상없으면그파이프에자료를쓸수있기를기다리던모든프로세스는커널로부터 SIGPIPE 시그널을받는다. 이때시그널이포착되지않으면해당프로세스는종료한다. 시그널이포착되면인터럽트루틴이수행된후에 write() 는 -1을반환한다. 이후에그파이프에자료를쓰려고시도하는프로세스도역시 SIGPIPE 시그널을받는다. 17

봉쇄되지않는 read 와 write 파이프에대한 read, write는봉쇄될수있다. 하지만, 어떤파이프에서자료를얻을때까지여러개의파이프를차례로조사 (poll) 하고자할때는봉쇄되면안된다. 이에 fcntl() 을사용하여해결한다. 예 ) fcntl(filedec, F_SETFL, O_NONBLOCK) 18

< ex_5.c > #include <fcntl.h> #include <errno.h> #define MSGSIZE 6 int parent (int *); int child (int *); char *msg1 = "hello"; char *msg2 = "bye!!"; main() { int pfd[2]; /* 파이프를개방한다 */ if(pipe (pfd) == -1) printf ("pipe call"); /* p[0] 의 O_NONBLOCK 플래그를 1 로설정한다 */ if (fcntl (pfd[0], F_SETFL, O_NONBLOCK) == -1) printf ("fcntl call"); 19

< ex_5.c > switch(fork()){ case 0: /* 자식 */ child(pfd); default: /* 부모 */ parent (pfd); int child(int p[2]) { int count; close (p[0]); for (count= 0; count < 3; count++) { write (p[1], msg1, MSGSIZE); sleep(3); /* 마지막메시지를보낸다 */ write (p[1], msg2, MSGSIZE); exit (0); 20

< ex_5.c > int parent (int p[2]) { int nread; char buf[msgsize]; close (p[1]); for(;;) { switch (nread = read(p[0], buf, MSGSIZE)){ case -1: /* 파이프에아무것도없는지검사한다. */ if (errno == EAGAIN){ printf ("(pipe empty)\n"); sleep (1); break; else printf ("read call"); case 0: /* 파이프가닫혔음. */ printf ("End of conversation\n"); exit (0); default: printf ("MSG=%s\n", buf); 21

다수의파이프취급 child 1 parent write( ) p[1] p[0] write( read( ) child 2 write( ) q[1] q[0] read( )) 22

select() Usage #include <sys/time.h> int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout); 23

< ex_6.c > #include <sys/time.h> #include <sys/wait.h> #include <stdio.h> #define MSGSIZE 6 char *msg1 = "hello"; char *msg2 = "bye!!"; void parent(int [][]); int child(int []); main() { int pip[3] [2]; int i; for (i = 0; i < 3; i++) { if (pipe(pip[i]) == -1) printf ("pipe call"); switch (fork()){ case 0: child (pip[i]); parent (pip); exit (0); 24

< ex_6.c > /* 부모는세개의파이프에전부귀를기울이고있다. */ void parent(int p[3][2]) { char buf[msgsize], ch; fd_set set, master; int i; /* 모든원하지않는화일기술자를닫는다 */ for (i = 0; i < 3; i++) close (p[i] [1]); /* select 시스템호출의비트마스크를설정한다. */ FD_ZERO (&master); FD_SET (0, &master); for (i = 0; i <3; i++) FD_SET (p[i] [0], &master); 25

< ex_6.c > /* 타임아웃없이 select 를호출한다. 사건이발생할때까지 select 는봉쇄될것이다 */ while (set = master, select (p[2] [0]+1, &set, NULL, NULL, NULL) > 0) { /* 표준입력, 즉화일기술자 0 에있는정보를잊어버리면안됨. */ if (FD_ISSET(0, &set)){ printf ("From standard input..."); read (0, &ch, 1); printf ("%c\n", ch); for (i = 0; i < 3; i++){ if (FD_ISSET(p[i] [0], & set)){ if (read(p[i][0], buf[msgsize])>0) { printf ("Message from child%d\n", i); printf ("MSG=%s\n",buf); /* 서버는모든자식이죽으면주프로그램으로복귀한다. */ if (waitpid (-1, NULL,WNOHANG) == -1) return; 26

< ex_6.c > int child(int p [2]) { int count; close (p[0]); for (count = 0; count < 2; count++) { write (p[1], msg1, MSGSIZE); /* 임의의시간동안중지한다. */ sleep (getpid() % 4); /* 최종메시지를보낸다. */ write (p[1], msg2, MSGSIZE); exit (0); 27

파이프와 exec() 호출 parent wait( ) grandchild (command1) child (command2) p[0] write( read( ) write( ) p[1] read( ) 28

< ex_7.c > #include <stdio.h> int join (char *com1[], char *com2[]) { int p[2], status; switch (fork()){ case 0: /* 자식 */ break; default: /* 부모 */ wait(&status); return (status); if (pipe(p) == -1) printf ("pipe call in join"); 29

< ex_7.c > switch (fork()){ case 0: dup2 (p[1],1); /* 표준출력이파이프로가게한다. */ close (p[0]); /* 화일기술자를절약한다. */ close (p[1]); default: execvp (com1[0], com1); printf("1st execvp call in join"); dup2(p[0], 0); /* 표준입력이파이프로부터오게한다 */ close (p[0]); close (p[1]); execvp (com2[0], com2); printf ("2nd execvp call in join"); 30

< ex_7.c > main() { char *one[4] = {"ls", "-l", "/usr/lib", NULL; char *two[3] = {"grep", " d", NULL; int ret; ret = join (one, two); printf ("join returned %d\n", ret); exit (0); 31

FIFO 와이름형파이프 파이프의결점 부모와자식프로세스간에만사용할수있다. 파이프는영구히존재할수없다. FIFO 파이프의결점을보완하기위한파이프의변종 영구적이며, UNIX 파일이름을부여받는다. 32

mkfifo() Usage #include <sys/types.h> #include <sys/stat.h> int mkfifo(const chat *pathname, mode_t mode); 33

< sendmsg.c > #include <fcntl.h> #include <stdio.h> #include <errno.h> #define MSGSIZ 63 char *fifo = "fifo"; main (int argc, char **argv) { int fd, j, nwrite; char msgbuf[msgsiz+1]; if ((fd = open(fifo, O_WRONLY O_NONBLOCK)) < 0) printf ("fifo open failed"); for ( j = 1; j < argc; j++) { if (strlen(argv[j]) > MSGSIZ) { fprintf (stderr, "message too long %s\n", argv[j]); continue; strcpy (msgbuf, argv[j]); if ((nwrite = write (fd, msgbuf, MSGSIZ+1)) == -1) printf ("message write failed"); exit (0); 34

< receivemsg.c > #include <fcntl.h> #include <stdio.h> #include <errno.h> #define MSGSIZ 63 char *fifo = "fifo"; main (int argc, char **argv) { int fd; char msgbuf[msgsiz+1]; if (mkfifo(fifo, 0666) == -1) { if (errno!= EEXIST) printf ("receiver: mkfifo"); if ((fd = open(fifo, O_RDWR)) < 0) printf ("fifo open failed"); for(;;) { if (read(fd, msgbuf, MSGSIZ+1) <0) printf ("message read failed"); printf ("message received:%s\n", msgbuf); 35