TLPI - Chapter 44 Pipe and Fifos

694 views
619 views

Published on

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
694
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
7
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

TLPI - Chapter 44 Pipe and Fifos

  1. 1. TLPI - Chapter 44 Pipe and Fifos Shu-Yu Fu (shuyufu at gmail.com)
  2. 2. Pipes ● Pipes can be used to pass data between related processes. $ ls | wc -l
  3. 3. Important Characteristics of Pipes ● A pipe is a byte stream ● Reading from a pipe ● Pipes are unidirectional ● Writes of up to PIPE_BUF bytes are guaranteed to be atomic ○ using fpathconf(fd, _PC_PIPE_BUF) to return the actual upper limit ● Pipes have a limited capacity ○ using fcntl(fd, F_SETPIPE_SZ, size) to change the capacity of the pipe referred to by fd ○ using fcntl(fd, F_GETPIPE_SZ) to get the capacity of the pipe referred to by fd
  4. 4. Creating and Using Pipes #include <unistd.h> int pipe(int filedes[2]);
  5. 5. Creating and Using Pipes (cont.) ● We can also use the stdio functions (printf(), scanf(), and so on) with pipes by first using fdopen() to obtain a file stream corresponding to one of the descriptors in fieldes. ○ Using ioctl(fd, FIONREAD, &cnt) to get the number of unread bytes in the pipe referred to by fd
  6. 6. A pipe has few uses within a single process
  7. 7. A pipe has few uses within a single process (cont.) ● If we require bidirectional communication, there is a simpler way: just create two pipes, one for sending data in each direction between the two processes. ○ deadlocks may occur if both processes block while trying to read from empty pipes or while trying to write to pipes that are already full
  8. 8. Closing unused pipe file descriptors ● Ensuring a process doesn't exhaust its limited set of file descriptors. ● It is only after all file descriptors in all processes that refer to a pipe are closed that the pipe is destroyed.
  9. 9. Pipes as a Method of Process Synchronization ● Listing 44-3: Using a pipe to synchronize multiple processes ● It can be used to coordinate the actions of one process with multiple other (related) processes. ● The fact that multiple (standard) signals can't be queued makes signals unsuitable in this case. But signals can be broadcasted by one process to all of the members of a process group.
  10. 10. Using Pipes to Connect Filters ● Listing 44-4: Using a pipe to connect ls and wc ● dup2() allows us to explicitly specify the descriptor to be bound int pfd[2]; pipe(pfd); if (pfd[1] != STDOUT_FILENO) { dup2(pfd[1], STDOUT_FILENO); close(pfd[1]; }
  11. 11. Talking to a Shell Command via a Pipe: popen() #include <stdio.h> FILE *popen(const char *command, const char *mode); int pclose(FILE *stream);
  12. 12. Pipes and stdio Buffering ● Since the file stream pointer returned by a call to popen() doesn't refer to a terminal, the stdio library applies block buffering to the file stream.
  13. 13. Pipes and stdio Buffering (cont.) ● When we call popen() with a mode of w, then output is sent to the child process only when the stdio buffer is filled or we close the pipe with pclose(). ○ using fflush() or setbuf(fp, NULL) to ensure the child process receives data immediately.
  14. 14. Pipes and stdio Buffering (cont.) ● If the process calling popen() is reading from the pipe, things may not be so straightforward. ○ Modifying the source code to include calls to setbuf() or fflush(). ○ Using pseudoterminal (Chapter 64)
  15. 15. FIFOs ● FIFOs are a variation on the pipe concept. The important difference is that FIFOs can be used for communication between any processes. ● A FIFO has a name within the file system and is opened in the same way as a regular file. $ mkfifo [ -m mode ] pathname or #include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode);
  16. 16. FIFOs (cont.) ● Opening a FIFO for reading blocks until another process opens the IFO for writing, and vice versa for writing. ○ Using O_NONBLOCK flag to prevent blocking. ● Using FIFOs and tee(1) to create a dual pipeline $ mkfifo myfifo $ wc -l < myfifo & $ ls -l | tee myfifo | sort -k5n
  17. 17. Nonblocking I/O (O_NONBLOCK flag) ● open() ○ It allows a single process to open both ends of a FIFO. ○ It prevents deadlocks between processes opening two FIFOs.
  18. 18. Nonblocking I/O (O_NONBLOCK flag) ● A deadlock ● O_NONBLOCK affects the semantics of subsequent read() and write() calls. ○ Using fcntl(fd, F_SETFL, flags) to enable/disable O_NONBLOCK bit.
  19. 19. Semantics of read() and write() on Pipes and FIFOs ● read()
  20. 20. Semantics of read() and write() on Pipes and FIFOs (cont.) ● write()

×