TLPI - Chapter 44 Pipe and Fifos

20
TLPI - Chapter 44 Pipe and Fifos Shu-Yu Fu (shuyufu at gmail.com)

description

 

Transcript of TLPI - Chapter 44 Pipe and Fifos

Page 1: TLPI - Chapter 44 Pipe and Fifos

TLPI - Chapter 44Pipe and Fifos

Shu-Yu Fu (shuyufu at gmail.com)

Page 2: TLPI - Chapter 44 Pipe and Fifos

Pipes

● Pipes can be used to pass data between related processes.$ ls | wc -l

Page 3: TLPI - Chapter 44 Pipe and Fifos

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

Page 4: TLPI - Chapter 44 Pipe and Fifos

Creating and Using Pipes

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

Page 5: TLPI - Chapter 44 Pipe and Fifos

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

Page 6: TLPI - Chapter 44 Pipe and Fifos

A pipe has few uses within a single process

Page 7: TLPI - Chapter 44 Pipe and Fifos

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

Page 8: TLPI - Chapter 44 Pipe and Fifos

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.

Page 9: TLPI - Chapter 44 Pipe and Fifos

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.

Page 10: TLPI - Chapter 44 Pipe and Fifos

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 boundint pfd[2];pipe(pfd);if (pfd[1] != STDOUT_FILENO) { dup2(pfd[1], STDOUT_FILENO); close(pfd[1];}

Page 11: TLPI - Chapter 44 Pipe and Fifos

Talking to a Shell Command via a Pipe: popen()#include <stdio.h>FILE *popen(const char *command, const char *mode);int pclose(FILE *stream);

Page 12: TLPI - Chapter 44 Pipe and Fifos

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.

Page 13: TLPI - Chapter 44 Pipe and Fifos

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.

Page 14: TLPI - Chapter 44 Pipe and Fifos

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)

Page 15: TLPI - Chapter 44 Pipe and Fifos

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 ] pathnameor #include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode);

Page 16: TLPI - Chapter 44 Pipe and Fifos

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

Page 17: TLPI - Chapter 44 Pipe and Fifos

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.

Page 18: TLPI - Chapter 44 Pipe and Fifos

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.

Page 19: TLPI - Chapter 44 Pipe and Fifos

Semantics of read() and write() on Pipes and FIFOs

● read()

Page 20: TLPI - Chapter 44 Pipe and Fifos

Semantics of read() and write() on Pipes and FIFOs (cont.)

● write()