Transcript Unix Pipes

Unix Pipes

Pipe sets up communication channel between two
(related) processes.
Two processes connected by a pipe
37



One process writes to the pipe, the other reads from
the pipe.
Looks exactly the same as reading from/to a file.
System call:
int fd[2] ;
pipe(&fd[0]) ;
fd[0] now holds descriptor to read from pipe
fd[1] now holds descriptor to write into pipe
Simple Example
#include <unistd.h> /* for Solaris */
#include <fcntl.h>
#include <stdio.h>
char *message = "This is a message!!!" ;
main()
{ char buf[1024] ;
int fd[2];
pipe(fd); /*create pipe*/
if (fork() != 0) { /* I am the parent */
write(fd[1], message, strlen (message) + 1) ;
}
else { /*Child code */
read(fd[0], buf, 1024) ;
printf("Got this from MaMa!!: %s\n", buf) ;
}
}
Create a Pipeline

Sometimes useful to connect a set of processes in a
pipeline.
Process
Pipe
c
Pipe
Process A writes to pipe AB,
Process B reads from AB and
writes to BC
Process C reads from BC and
writes to CD …..
Process
D
Inherited File Descriptors

Process created with three files: stdin, stdout, and
stderr (file descriptors 0, 1, 2).


write(1, “EEEE”, 10) ; // goes to stdout (terminal) or printf
read(0, buf, 4) ; //read from terminal
Redirecting stdin and stdout

Can due on command line:




./a.out > tmp // write output to tmp rather than terminal.
./a.out < foo // read from foo not terminal.
When processing in a pipeline useful to redirect
stdout of pipe n to stdin of pipe n+1.
Key: When Unix allocates file descriptor, it always
chooses the lowest available.

If close stdin and open new file, e.g., close(0), fd =
open(“foo”, ….) then fd = 0 and all subsequent reads from
stdin will read instead from “foo”.
main()
{
int fd ;
printf("this goes to stdout\n");
close(1);
/* close stdout */
fd = open("foo",O_CREAT | O_WRONLY); /* fd = 1! */
printf("fd = %d\n", fd) ; //goes to file "foo"
printf("Should not see this either!\n") ;//ditto
}
Dup System Call

int dupfd = dup(fd);

Duplicates a file descriptor -- “aliased”



Both point to same file, that being the argument to dup.
Reads/writes from fd and dupfd going to the same file.
Useful for situation such as:
 want to write some output to standard out,
then to a file, then back to standard out -- all
using printf.
 Redirecting I/O for pipeline.
pipeline (process1, process2) /* program names */
char *process1, *process2 ;
{ char buf[1024] ;
int fd[2];
pipe(&fd[0]); /*create pipe*/
if (fork() != 0) { /* parent */
close(fd[0]); //don't need.
close(STD_OUTPUT);
dup(fd[1]);
/* sets stdout to this pipe end */
close(fd[1]) ; //don’t need. Already set stdout to pipe.
execl(process2,process2,0);
}
else {
/* child */
close(fd[1]);
close(STD_INPUT);
dup(fd[0]);
/* replace stdin */
close(fd[0]);
execl(process1,process1,0);
}
fork()
exec
exec
stdout
stdin
Single and Multithreaded
Processes
Benefits

Responsiveness: Separate thread to handle user
input.




Web server spawns separate thread to handle incoming
request.
Resource Sharing: e.g., one code, data segment.
Economy: Much cheaper to create and switch than
processes.
Utilization of MP Architectures: Assign each thread to
a separate processor if available.

Lightweight process.


State:


Threads share all process resources.
Thread ID, program counter, register set, and stack.
User-level threads and kernel-level threads.
User Threads


Thread management done by user-level threads
library.
Advantages:


Very fast: Does not involve kernel in creation, scheduling, or
switching.
Disadvantages:

When a thread blocks, whole process blocks.
Kernel Threads

Supported by the Kernel.


Advantage:



Kernel creates, schedules, and switches threads.
When one thread blocks, the whole process does not have
to block.
Thus can overlap I/O and computation.
Disadvantage:

Slower since kernel is involved.
Multithreading Models

Many-to-One

One-to-One

Many-to-Many
Many-to-One


Many user-level threads mapped to
single kernel thread.
Used on systems that do not support
kernel threads.
Many-to-One Model
One-to-One


Each user-level thread maps to kernel
thread.
Examples
- Windows 95/98/NT/2000
- OS/2
One-to-one Model
Many-to-Many Model




Allows many user level threads to be
mapped to many kernel threads.
Allows the operating system to create a
sufficient number of kernel threads.
Solaris 2
Windows NT/2000 with the ThreadFiber
package
Many-to-Many Model
Threading Issues


Semantics of fork() and exec() system
calls.
Thread cancellation.
Pthreads



a POSIX standard (IEEE 1003.1c) API
for thread creation and synchronization.
API specifies behavior of the thread
library, implementation is up to
development of the library.
Common in UNIX operating systems.
Solaris 2 Threads
Solaris Process
Windows 2000 Threads


Implements the one-to-one mapping.
Each thread contains
- a thread id
- register set
- separate user and kernel stacks
- private data storage area