0% found this document useful (0 votes)
121 views16 pages

Today's Topic: - Inter-Process Communication With Pipes

This document discusses several topics related to inter-process communication in Unix/Linux systems, including pipes, files, timestamps, and signals. It provides code examples of creating unnamed pipes between processes using the pipe() system call and redirecting standard input/output. It also discusses how the shell implements the pipe operator to connect the output of one process to the input of another.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
121 views16 pages

Today's Topic: - Inter-Process Communication With Pipes

This document discusses several topics related to inter-process communication in Unix/Linux systems, including pipes, files, timestamps, and signals. It provides code examples of creating unnamed pipes between processes using the pipe() system call and redirecting standard input/output. It also discusses how the shell implements the pipe operator to connect the output of one process to the input of another.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 16

Today’s topic

• Inter-process communication with pipes


• More about files and I/O.
– cin  read (0, …)
– cout  write (1, …)
– What happens when we use both I/O
mechanisms in the same program?
• Check out the output of mix.cpp?
– Why?
– The liberty in the implementation of the
C/C++ runtime library
• How to fix the order? fflush(0).
• More on the timestamp of a file
– How to get the info? Stat
– See newstat.c for comparing the timestamp of
two files.
• Inter-Process Communication (IPC):
– processes may be collaborated on tasks
– e.g,
ps -ef | grep a.out | more
– e.g,

client server

– OS needs to provide mechanisms for IPC


• IPC related system calls:
– the most general IPC mechanism in UNIX is
socket (send and receive paradigm with
read/write interface, works also for processes on
different machines).

– What we will discuss:


• pipes: allow transfer of data between processes in a
first-in-first-out manner.
• signal: send a flag to another process
• Pipes:
– two types of pipes, named pipes and unnamed
pipes
– name pipes:
• like a file (create a named pipe (mknod), open,
read/write)
• can be shared by any number of processes
• will not be discussed in detail.
– Unnamed pipes:
• an unnamed pipe does not associated with any file
• can only be shared by related processes (descendants
of a process that creates the unnamed pipe).
• Created using system call pipe().
• Pipes and files
– Both can be used to share information among
processes
– Both share the file API

– Performance difference:
• A pipe is usually realized in memory, a file is not.
• Pipe operations are memory operations, file operations
are I/O operations.
– Semantic difference:
• A pipe is a fifo queue:
– The content in a fifo queue can only be read once (the
information is gone after the read operation).
• A storage in a file is persistent
– The content can be used many times.
• The pipe system call
– open unnamed pipes
– syntax
int pipe(int fds[2])
– semantic
create a pipe and returns two file descriptors fds[0] and
fds[1]

a read from fds[0] accesses the data written to fds[1] on


a fifo basis.

the pipe has a limited size (64K in most systems) --


cannot write to the pipe infinitely.
#include <unistd.h>
#include <stdio.h>
main()
{
char *s, buf[1024];
int fds[2];
s = “hello world\n”;
pipe(fds);
write(fds[1], s, strlen(s));
read(fds[0], buf, strlen(s));
printf(“fds[0] = %d, fds[1] = %d\n”, fds[0], fds[1]);
write(1, buf, strlen(s));
}

/* example1.c */
#include <unistd.h>
#include <stdio.h>
main()
{
char *s, buf[1024];
int fds[2];
s = “hello world\n”;
pipe(fds);
if (fork() == 0) {
printf(“child process: \n”);
write(fds[1], s, 12); exit(0);
}
read(fds[0], buf, 6);
write(1, buf, 6);
}
/* example2.c : using pipe with fork*/
IPC can be used to enforce the order of the execution of processes.
main()
{
char *s, buf[1024]; 11111 33333 11111 33333
int fds[2]; 22222 44444 33333 11111
s = “hello world\n”; 33333 11111 22222 22222
pipe(fds); 44444 22222 44444 44444
if (fork() == 0) {
printf(“11111 \n”); /* how to make 111111 before 444444 */
read(fds[0], s, 6);
printf(“22222\n”);
} else {
printf(“33333\n”);
write(fds[1], buf, 6);
printf(“44444\n”)
}
} /* example3.c */
• Anyone writes any programs that take
advantage of multi-core in a CPU?
– A multiple process solution for computing
PI?
• See pi1.c and pi2.c?
• Implementing Pipe in shell.
E.g. /usr/bin/ps -ef | /usr/bin/more
• How shell realizes this command?
– Create a process to run ps -ef
– Create a process to run more
– Create a pipe from ps -ef to more
• the standard output of the process to run ps -ef is
redirected to a pipe streaming to the process to run
more
• the standard input of the process to run more is
redirected to be the pipe from the process running
ps -ef
• Implement “/bin/ps -ef | /bin/more” – first try
main() {
int fds[2];
char *argv[3];
pipe(fds); // create pipe
if (fork() == 0) {
close(0); dup(fds[0]); // redirect standard input to fds[0]
argv[0] = “/bin/more”; argv[1] = 0;
if (execv(argv[0], argv) == -1) exit(0);
} if (fork() == 0) {
close(1); dup(fds[1]); // redirect standard output to fds[1];
argv[0] = “/bin/ps”; argv[1] = “-ef”; argv[2] = 0;
if (execv(argv[0], argv) == -1) exit(0);
}
wait(); wait();
} /* example4a.c */
• Example4a.c not the same as “/bin/ps –ef |
/bin/more”, what is missing?
– When can ‘more’ be done?
• When the end of the file is reached.

– What is “the end of file” of a pipe?


• No data in pipe?
• No data in pipe and no potential writer to the pipe!!!!

– In example4a.c, the more program will not finish


since there are potential writers.
• How to fix this program?
• Implement “/bin/ps -ef | /bin/more”
main() {
int fds[2];
char *argv[3];
pipe(fds); // create pipe
if (fork() == 0) {
close(0); dup(fds[1]); // redirect standard input to fds[1]
close(fds[0]); close(fds[1]); // close unused files
argv[0] = “/bin/more”; argv[1] = 0;
execv(argv[0], argv);
exit(0);
} if (fork() == 0) {
close(1); dup(fds[0]); // redirect standard output to fds[0];
close(fds[0]); close(fds[1]); // close unused files
argv[0] = “/bin/ps”; argv[1] = “-ef”; argv[2] = 0;
execv(argv[0], argv);
exit(0);
}
close(fds[0]); close(fds[1]); wait(); wait();
} /* example4.c */

You might also like