0% found this document useful (0 votes)
1 views14 pages

PDF Document

The document discusses the concept of pipes as an interprocess communication (IPC) mechanism in UNIX and MS-DOS. It explains how to create and use pipes for communication between related processes, including the use of the fork() system call to duplicate processes and the dup2() function to redirect standard input and output. Examples are provided to illustrate the implementation of pipes and communication between parent and child processes.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views14 pages

PDF Document

The document discusses the concept of pipes as an interprocess communication (IPC) mechanism in UNIX and MS-DOS. It explains how to create and use pipes for communication between related processes, including the use of the fork() system call to duplicate processes and the dup2() function to redirect standard input and output. Examples are provided to illustrate the implementation of pipes and communication between parent and child processes.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

CENG460

Operating Systems
Spring 2021 -2022
Interprocess communications
(IPC) (2)

[Operating Systems Concepts, 8th Edition, by Silberschatz, Galvin,


and Gagne, 2009]

1
B.2 Pipes
O Pipes are one of the most ancient, yet simple and useful, IPC
mechanisms provided by UNIX
O They’ve also been available in MS-DOS from the beginning

O In UNIX, a pipe is mono-directional, one end for read and


one end for write.
O Two pipes must be used for bi-directional communication

O Pipes can be used to create communication


channel between related processes (What is
related processes !! (next slides)
2
B.2 Pipes
O Example call to pipe() If successful the call will
return two integer file
int fd[2]; descriptors that reference
if (pipe(fd)) two data streams: fd[0] and
{ fd[1]
perror(“pipe()”);
exit(1); fd[0] is the read-end
} fd[1] is the write-end
O A pipe is used to establish communications between a pair of processes.
The system call to create a pipe is pipe()
O . The array pipe fd is used to return two file descriptors referring to the
ends of the pipe.
O Pipe fd[0] refers to the read end of the pipe.
O Pipe fd[1] refers to the write end of the pipe
O Data written to the write end of the pipe is buffered by the kernel until it
is read from the read end of the pipe.
O On success, 0 is returned. On error, -1 is returned, and errno is set
,3
appropriately.
B.2 Pipes Using pipes
O Creating a pipe
O int pfd[2];
O pipe(pfd);
Pipes
B.2 Fork and pipe
O A process is duplicated using fork() and two identical
processes exist.
O A pipe created before the fork() call becomes shared
between the two processes and can be used for
inter-process communication
After
fork
Before fork
Pipes
B.2 Fork and pipe
O As result there are two read ends and two write
ends.
O Either process can write into the pipe, and
either can read from it.
O One of the processes must close its read end,
and the other must close its write end. The
result is a simple pipeline again.
Pipes
B.2 Fork and pipe
O Suppose the parent wants to communicate
with the client and writes down a pipeline.
O The parent closes its read end, and writes into
the other end.
O The child closes its write end and reads from
the other end.
O In this manner the information is clearly sent
from the parent to the child.
Steps to communicate via pipes
with Fork
O Create the pipes needed
O Generate the child process(es)
O Close/duplicate file descriptors to properly
associate the ends of the pipe.
O Close the unneeded ends of the pipe
Perform the communication activities
O Close the remaining open file descriptors
O If appropriate, wait for the child process to
terminate
Pipes
B.2 Pipes Example
int fd[2];
pipe(fd);
int i = fork();
if (i==0)
{
char buffer[64] = “ Hello Father ”;
close(fd[0]);
printf(“ I am the child my pid is %d \n”, getpid());
write(fd[1], buffer, 64);
close(fd[1]);
}
else
{
char buffer[64] ;
close(fd[1]);
printf(“ I am the father my pid is %d \n”, getpid());
read(fd[0], buffer, 64);
prinf(“My son wrote %s \n “,buffer);
close(fd[0]); 9
}
exit(0);
B.2 Pipes and exec()
• A pipeline works because both processes know the file
descriptor (fd) of each end of the pipe.
⇒ As the processes have a stdin (fd=0),
a stdout (fd=1) and a stderr (fd=2) open.

• Sometimes, we need to communicate with a child process


that execs some executables

• In this case the process replace itself with new process


that use stdin and stdout respectively by calls to execlp()
⇒ the new processes have file descriptors 0, 1, 2, 3 & 4
open.
10
B.2 Pipes and exec()
Sometimes, we need to communicate with a child process
that execs some executables
– e.g., fork of a child that runs “/bin/ls” and retrieve its output
In this case, one can’t put code in that executable to tell it to
write its output to the write-end of a pipe
• So: how can we establish communication?
• The problem can be solved by overriding some
standard file descriptors with the end of a pipe
• A standard way to do I/O for a process is to use stdin and
stdout (system programs do this)
• These file descriptors are set as follows
– stdin: 0
– stdout: 1
– stderr: 2 11
B.2 Pipes and exec()
There is a system call to duplicate a fd (file descriptor)
O Another number through which to access the “file”
O dup (int oldfd) generates a new number for
oldfd
O e.g., dup(1) returns a new fd number for the stdout fd.
The process can now write to the new fd number to
generate output.
O dup2 (int oldfd, int newfd) specifies
the number of the new fd
O e.g. dup2(40, 0): the process’ stdin now comes from
fd 40
O e.g. dup2(30, 1); the process’ stdout now goes to fd 30

12
B.2 Pipes and exec()
O We can now do communication either way:

O create a pipe: fd[0] (read-end) and fd[1] (write-end)


O Fork a child
O Either parent or child process can do one of the following:
O dup2(fd[1], 1); ; the process’ stdout now goes to fd[1] (write to
the pipe)

O dup2(fd[0], 0); ; the process’ stdin now comes from fd[0] (read
from pipe)

13
Example
Child process
#include <sys/types.h>
#include <unistd.h> if (!pid)
{ Duplicate stdout
#include <stdio.h>
#include <stdlib.h> dup2(fd[1], 1);
#include <string.h> close(fd[0]);
int main() execl("/bin/date", "date",
Create pipes
{ NULL);
exit(0); Run a command
pid_t pid; Create a buffer
int fd[2];
}
and set to 0 End of child
if (pipe(fd) == -1)
close(fd[1]);
char buffer[64]; process
{
bzero(buffer,64);
perror("pipe()");
if (read(fd[0], buffer, 64) == -1)
exit(1);
{
} Create child perror("read()");
pid = fork(); Read what the
exit(1);
if (pid < 0) child wrote
}
{ fprintf(stdout,"Output from child:
perror("fork()"); %s",buffer);
exit(1); 14
close(fd[0]);
} exit(0);
}

You might also like