System Programming:Communication through pipes
Raymond NamystDept. of Computer Science
University of Bordeaux, France
https://gforgeron.gitlab.io/progsys/
1
The concept of pipe
• Major mechanism used by the shell• ls | grep pattern• ./prog | cat -n | less• Etc.
• Some operating systems (MS-DOS) implement pipes using files• Example: ls | grep pattern
• The output of “ls” is redirected to a temporary file• The system waits for the termination of “ls”• “grep pattern” is executed, with its input redirected from the file
• No parallelism• Max file size limit can be reached
2
The concept of pipe
• In Unix systems, pipes are special objects allocated in the kernel• FIFO ordering• Fixed capacity
3
The concept of pipe
• In Unix systems, pipes are special objects allocated in the kernel• FIFO ordering• Fixed capacity
• The “pipe” syscallint pipe(int fildes[2]);
• Creates a pipe and returns two file descriptors• One for reading (fildes[0]) and one for writing (fildes[1])
4
fildes[1] fildes[0]
The concept of pipe
• In Unix systems, pipes are special objects allocated in the kernel• FIFO ordering• Fixed capacity
• The “pipe” syscallint pipe(int fildes[2]);
• Creates a pipe and returns two file descriptors• One for reading (fildes[0]) and one for writing (fildes[1])
• Reading and writing are done using usual read/write• No lseek
5
write read
int tube[2];pipe (tube);
- 6
process
filedescriptor
table
0
12
3
4
5
6
7
…
3tube
Opened files table
Mode: RD_ONLYOffset: 0Ref counter: 1File info:
4
Mode: WR_ONLYOffset: 0Ref counter: 1File info: write read
int tube[2];pipe (tube);
- 7
process
filedescriptor
table
0
12
3
4
5
6
7
…
3tube 4
write read
Simplified view
Trying out our first pipe
• pipe.c
8
Pipe are intended to allow communication between processes• But pipes created with “pipe” are anonymous
• No way to share their name• Look at mkfifo if named pipes are really what you need
• Fortunately, pipes are inherited when forking new processes…
9
int tube[2];pipe (tube); fork();
- 10
parent
filedescriptor
table
0
12
3
4
5
6
7
…
3tube 4
child
0
12
3
4
5
6
7
…
3tube 4
write read
Sending characters through a pipe
• Hand-made implementation of• Line numbering + to upper case
• pipe-n-fork.c
11
father child
file
Touppercat -n
stdout
The concept of pipe
• When both sides of a pipe are opened• read is blocking if the pipe is empty• write is blocking if the pipe is full
12
The concept of pipe
• When both sides of a pipe are opened• read is blocking if the pipe is empty• write is blocking if the pipe is full
• Pipe closed on the write side• read returns 0 (end of file)
13
The concept of pipe
• When both sides of a pipe are opened• read is blocking if the pipe is empty• write is blocking if the pipe is full
• Pipe closed on the write side• read returns 0 (end of file)
• Pipe closed on the read side• write raises an exception (“Broken pipe”)
14
Sending characters through a pipe
• Redirections to only use STDIN/STDOUT • pipe-n-redir.c
15
father child
file
Touppercat -n
stdout
Sending characters through a pipe
• Redirections to only use STDIN/STDOUT • Exec to use legacy
• cat -n• tr a-z A-Z
• pipe-n-exec.c
16
father child
file
tr a-z A-Zcat -n
stdout
Sending characters through a pipe
• Problem:• Child still output characters after
shell prompt
• One solution would be to swap roles of father & child…
17
father child
file
tr a-z A-Zcat -n
stdout
Sending characters through a pipe
• Problem:• Child still output characters after
shell prompt
• But the shell acts differently: it creates two childs!
• ultimate-pipe.c
18
Child 1 Child 2
file
tr a-z A-Zcat -n
stdoutFather
fork fork
Setting up a chain of processes
• chain.c
19
P1 PN-1
Cmd N-1Cmd 1
stdout
P0
Cmd 0
stdin
…
Atomicity of read/write
• What happens if multiple processes simultaneously write into (or read from) the same pipe?• Atomic if size < PIPE_BUF
• (typically 512 bytes)
20
writeread
writeread
read
Additional resourcesavailable on
http://gforgeron.gitlab.io/progsys/
21