300 likes | 804 Views
[Unix Programming] Interprocess Communication - FIFO. Young-Ju, Han Email: yjhan@imtl.skku.ac.kr Website : http://imtl.skku.ac.kr/~yjhan. Contents. FIFO. FIFOs or named pipes. drawbacks of pipe only be used to connect related processes cannot be permanent FIFOs named pipes
E N D
[Unix Programming]Interprocess Communication - FIFO Young-Ju, Han Email: yjhan@imtl.skku.ac.kr Website : http://imtl.skku.ac.kr/~yjhan
Contents • FIFO 2005 UNIX Programming
FIFOs or named pipes • drawbacks of pipe • only be used to connect related processes • cannot be permanent • FIFOs • named pipes • unrelated process can exchange data • a type of file (st _mode member of the stat structure) • S_ISFIFO macro • have a access permissions, ownership • using the normal file I/O functions • open(), read(), write(), unlink(), close(), etc 2005 UNIX Programming
FIFOs or named pipes • command level (Example) create and use a FIFO $ /etc/mknod channel p or $mkfifo channel $ ls –l channel prw-rw-r-- 1 ben usr 0 Jun 1 21:05 channel $ cat < channel FIFO에 write하는 프로세스가 생길 때까지 blocking 된다 $ cat < channel & [1] 20779 $ ls –l > channel; wait 2005 UNIX Programming
FIFOs or named pipes • Programming with FIFOs • create a FIFO • once created, must be opened using open • 생성될 때 process의 umask 적용됨 #include <sys/types.h> #include <sys/stat.h> int mkfifo (const char *pathname, mode_t mode); 0 : ok -1 : error FIFO name permission 2005 UNIX Programming
FIFOs or named pipes • Programming with FIFOs #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> mkfifo(“/tmp/fifo”, 0666); fd = open(“/tmp/fifo”, O_WRONLY); block if no reader fd = open(“/tmp/fifo”, O_RDONLY); block if no writer return immediately if no writer fd = open(“/tmp/fifo”, O_RDONLY |O_NONBLOCK); -1 : ENXIO if no reader fd = open(“/tmp/fifo”, O_WRONLY |O_NONBLOCK); return immediately fd = open(“/tmp/fifo”, O_RDWR); 2005 UNIX Programming
FIFOs or named pipes • Programming with FIFOs • rules • write (no reader) • SIGPIPE generated • last write close • ‘end of file’ is generated for reader • PIPE_BUF • maximum amount of data that can be written atomically to a FIFO • example • shell commands to pass data from one shell pipeline to another, without creating intermediate temporary files • a client-server application to pass data between the clients and server 2005 UNIX Programming
Example – Using FIFOs to Duplicate Output Streams $ mkfifo fifo1 $ prog3 < fifo1 & $ prog1 < infile | tee fifo1 | prog2 prog3 input file prog1 prog2 Procedure that process a filtered input stream twice prog3 FIFO input file prog1 tee prog2 Using a FIFO and tee to send a stream to two different processes tee command : copy its standard input to both its standard output and to the file named on its command line 2005 UNIX Programming
Example : Client-Server Communication Using a FIFO • Clients sending requests to a server using a FIFO server read requests well-known FIFO write requests write requests client client ... 2005 UNIX Programming
Example : Client-Server Communication Using a FIFO • Client-server communication using FIFOs server write replies write replies read requests client-specific FIFO well-known FIFO client-specific FIFO write replies read replies write requests write requests client client ... 2005 UNIX Programming
Example : Sendmessage • sendmessage (FIFO를 통해 메시지를 보낸다) #include <fcntl.h> #include <stdio.h> #include <errno.h> #define MSGSIZ 63 char *fifo = "fifo"; void fatal (char *msg){ fprintf(stderr, “%s\n”,msg); exit(1);} int main (int argc, char **argv){ int fd, j, nwrite; char msgbuf[MSGSIZ+1]; if (argc < 2){ fprintf (stderr, "Usage: sendmessage msg ... \n"); exit(1); } /* O_NONBLOCK을 설정하여 fifo를 개방한다. */ if ((fd = open(fifo, O_WRONLY | O_NONBLOCK)) < 0) fatal ("fifo open failed"); 2005 UNIX Programming
Example : Sendmessage • sendmessage /* 메시지를 보낸다. */ 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) fatal ("message write failed"); } exit (0); } 2005 UNIX Programming
Example : recvmessage • recvmessage (FIFO를 통해 메시지를 보낸다.) #include <fcntl.h> #include <stdio.h> #include <errno.h> #define MSGSIZ 63 char *fifo = "fifo"; void fatal (char *msg){ fprintf(stderr, “%s\n”,msg); exit(1);} int main(int argc, char **argv){ int fd; char msgbuf[MSGSIZ+1]; /* fifo가 이미 존재하지 않으면, 생성한다 */ if (mkfifo(fifo, 0666) == -1){ if (errno != EEXIST) fatal ("receiver: mkfifo"); } /* fifo를 읽기와 쓰기용으로 개방한다. */ if ((fd = open(fifo, O_RDWR)) < 0) fatal ("fifo open failed"); 2005 UNIX Programming
Example : recvmessage • recvmessage $recvmessage & [1] 25845 $sendmessage message 1 message received: message message received: 1 $sendmessage ‘message 1’ message received: message 1 /* 메시지를 받는다 */ for(;;) { if (read(fd, msgbuf, MSGSIZ+1) <0) fatal ("message read failed"); /* * 메시지를 프린트한다 ; 실제로는 보다 흥미 있는 일이 수행된다. */ printf ("message received:%s\n", msgbuf); } } 2005 UNIX Programming
exec sh ps fork fork pipeline exec fork sh proc1 exec pipeline Appendix • processes when invoked by Bourne shell $ ps | proc1 | proc2 sh sh proc2 2005 UNIX Programming