240 likes | 575 Views
Lecture 09. Pipes. Outline. Pipes in General pipe() system call pipe() and fork() Closing Unused File Descriptors pipe() and dup2() Live Coding. Pipes. Pipes are the oldest type of interprocess communication (IPC) in UNIX The output of one process becomes the input of another.
E N D
Lecture 09 Pipes
Outline • Pipes in General • pipe() system call • pipe() and fork() • Closing Unused File Descriptors • pipe() and dup2() • Live Coding
Pipes • Pipes are the oldest type of interprocess communication (IPC) in UNIX • The output of one process becomes the input of another
Pipes (Example) UNIX> ls | wc –l • | => shell command to pipe processes together • pipe the output of process ls to the process wc –l
Pipes (Example) UNIX> ls | wc –l • stdout from lsprocess joined with write end of pipe • stdinof wcprocess joined with read end of pipe • Two processes are unaware of pipe • (Just writes to stdout/ reads from stdin) • Pipe creates IPC pipe wc -l stdin (f 0) ls stdout (fd 1) write end read end
Pipes UNIX> ls | wc –l Shell • Creates a pipe • Creates two child processes using fork() and exec() • Child #1 duplicatesstdout with write end of pipe • Child #2 duplicatesstdinwith read end of pipe • Parentand childrenclose all unused FDs
Pipes • Pipe data is just a stream of bytes • Cannot use lseek() with a pipe • To send discrete messages, use alternate IPC methods • Sockets • Message queues • etc.
Reading from a Pipe • Read will block until a byte is present in pipe • When write end of pipe is closed, read will see EOF
Pipes are Unidirectional • Data can travel only in one direction • One end used for writing • The other end used for reading • Want bidirectional IPC? Use sockets..
Outline • Pipes in General • pipe() system call • pipe() and fork() • Closing Unused File Descriptors • pipe() and dup2() • Live Coding
pipe() int pipe ( intfd[2] ); • #include <unistd.h> • Returns 0 on success • Returns -1 on error • pipe() returns two file descriptors in fd array • fd[0] => read end of pipe • fd[1] => write end of pipe
pipe() int pipe ( intfd[2] ); • After pipe(), can use normal I/O system calls on fd[0] and fd[1] • Can also use C I/O functions: fprintf, fscanf, etc. • Use fdopen() to obtain a FILE * from file descriptor
pipe() • After pipe(), calling process has FDs to both ends: calling process fd[1] fd[0] pipe
Outline • Pipes in General • pipe() system call • pipe() and fork() • Closing Unused File Descriptors • pipe() and dup2() • Live Coding
pipe() and fork() parent process fd[1] fd[0] • Pipes often used for IPC between parent and child • Remember: after fork(), child inherits copies of parent’sFDs pipe child process fd[1] fd[0] after fork()
pipe() and fork() parent process fd[1] • One process should close unusedread end of pipe • Other process should close unusedwriteend of pipe • E.g., if parent wants to send data tochild, parent would close fd[0] (read end), child would close fd[1] (write end) pipe child process fd[0] after closing unused FDs
Outline • Pipes in General • pipe() system call • pipe() and fork() • Closing Unused File Descriptors • pipe() and dup2() • Live Coding
Closing Unused FDs • Essential to correct use of pipes • Process on reading end of pipe must closewrite end • Else the truewrite end of pipe will never send EOF • Why? Because the a write end of the pipe is still open • ==> Read from pipe will block forever
Closing Unused FDs • Essential to correct use of pipes • Process on writing end of pipe must close read end • Else data can still be written to pipe even after read end is closed • Moral of the story? Always close unused pipe FDs
Outline • Pipes in General • pipe() system call • pipe() and fork() • Closing Unused File Descriptors • pipe() and dup2() • Live Coding
Using Pipes to Connect Filters • Many pipes can be linked together, e.g., UNIX> ls –l | head –n 3 | wc –c | ... • stdout from the left process is piped to stdinof right process... • Shell does this by duplicatingstdoutof left process to write end of pipe ( fd[1] ) ... and duplicatingstdinof right process to read endof pipe ( fd[0] )
Using dup2() with pipe() dup2( fd[1], 1 ) • Close file descriptor 1 ( stdout ) • Reopen file descriptor 1 bound to write end of pipe ( fd[1] ) • After dup2(), now have two FDs referring to write end of pipe • File descriptor 1 ( stdout) • fd[1] • Must then close fd[1] ( duplicated descriptor )
Outline • Pipes in General • pipe() system call • pipe() and fork() • Closing Unused File Descriptors • pipe() and dup2() • Live Coding
Live Coding • Create pipe, fork child process, IPC between parent / child • Create pipe, fork / exec new program, IPC between parent / new program • Recreate “ls | wc –l” (create pipe, fork two processes, dup, exec)