140 likes | 307 Views
Pipes. Pipes are an inter-process communication mechanism that allow two or more processes to send information to each other. Pipes. A pipe provides a one-way flow of data example: who | sort| lpr output of who is input to sort output of sort is input to lpr. who. pipe. sort. pipe.
E N D
Pipes Pipes are an inter-process communication mechanism that allow two or more processes to send information to each other
Pipes • A pipe provides a one-way flow of data • example: who | sort| lpr • output of who is input to sort • output of sort is input to lpr who pipe sort pipe lpr Bytes from “who” flow through the pipe to “sort” Bytes from “sort” flow through the pipe to “lpr”
Pipes • Pipe is a data structure in the kernel. • int pipe(intfd[2]) • create an unnamed pipe and return two file descriptors • fd[0] is the “read” end of the pipe • fd[1] is the “write” end of the pipe
Description of pipe() Write end fd[0] Pipe fd[1] Read end
#include <stdio.h> #define READ 0 #define WRITE 1 char* phrase = "Stuff this in your pipe and smoke it"; main () { int fd [2], bytesRead; char message [100]; pipe (fd); /*Create an unnamed pipe */ if (fork () == 0) { close(fd[READ]); write (fd[WRITE],phrase, strlen (phrase) + 1); close (fd[WRITE]); } else { close (fd[WRITE]); bytesRead = read (fd[READ], message, 100); printf ("Read %d bytes: %s\n", bytesRead, message); close (fd[READ]); } } [c33225@snowball ~]$ ./talk Read 37 bytes: Stuff this in your pipe and smoke it
parent process child process fork readfd readfd writefd writefd pipe flow of data kernel UNIX Pipe Creation • First, a process creates a pipe, and then forks to create a copy of itself.
parent process child process fork readfd writefd pipe flow of data kernel Pipe Examples Parent opens file, child reads file • child closes read end of pipe • parent closes write end of pipe
Named Pipes • Named pipes [often referred to as first-in, first-out queues (FIFOs)] are less restricted than unnamed pipes and have the advantages: • Have a name that exists in the file system • May be used by unrelated processes • Exist until they are explicitly deleted
Named Pipes • To create a named pipe: • Using UNIX mknod utility • Using mknod() system call
mknod utility [c33225@snowball ~]$ mknod myPipe p [c33225@snowball ~]$ chmod ug+rw myPipe [c33225@snowball ~]$ ls -lg myPipe prw-rw-r-- 1 c33225 0 Jul 23 16:07 myPipe Create a named pipe using mknod, use the p option The mode of the named pipe may be set using chmod
Named Pipes If a process tries to open a named pipe for read only and no process currently has that file open for reading, the writer waits until the file is open. Similarly for a writer process. Named pipes do not work across networks We need socket to do communication among processes across networks
reader.c #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int readLine (int fd, char *str); main () { int fd; char str[100]; unlink(“aPipe”); /* Remove named pipe if it already exists */ mknod (“aPipe”, S_IFIFO, 0); /* Create named pipe */ chmod (“aPipe”, 0660); /* Change its permissions */ fd = open (“aPipe”, O_RDONLY); /* Open it for reading */ while (readLine (fd, str)) /* Display received messages */ printf (“%s\n”, str); close (fd); /* Close pipe */ } int readLine (int fd, char *str) /* Read a single NULL-terminated line into str from fd */ /* Return 0 when the end-of-input is reached and 1 otherwise */ { int n; do /* Read characters until NULL or end-of-input */ { n = read (fd, str, 1); /* Read one character */ } while (n > 0 && *str++ != NULL); return (n > 0); /* Return false if end-of-input */ }
writer.c #include <stdio.h> #include <fcntl.h> main () { int fd, messageLen, i; char message [100]; /* Prepare message */ sprintf (message, "Hello from PID %d", getpid ()); messageLen = strlen (message) + 1; do /* Keep trying to open the file until successful */ { fd = open ("aPipe", O_WRONLY); /* Open named pipe for writing */ if (fd == -1) sleep (1); /* Try again in 1 second */ } while (fd == -1); for (i = 1; i <= 3; i++) /* Send three messages */ { write (fd, message, messageLen); /* Write message down pipe */ sleep (3); /* Pause a while */ } close (fd); /* Close pipe descriptor */ } $ ./reader & ./writer & ./writer & [1] 3152 [2] 3153 [3] 3154 $ Hello from PID 3153 Hello from PID 3154 Hello from PID 3154 Hello from PID 3153 Hello from PID 3154 Hello from PID 3153 jobs [1] Done ./reader [2]- Done ./writer [3]+ Done ./writer