Transcript The Process

The Process
CIS 370, Fall 2009
CIS UMassD
The notion of a process
In UNIX a process is an instance of a
program in execution
A job or a task
Each process has program code, data
segment, program stack etc.
The shell (or any command interpreter)
starts a process for each command
submitted.
Process examples
$ cat file1 file2
results in the shell creating a process
specifically for running this command
$ ls | wc
results in the shell creating two processes where
the output of ls is sent (via the pipe) as in input
to wc
Processes are different from programs
a single program may create several processes.
How to create a process
UNIX provides several mechanisms for
creating processes.
fork - creates a new process by duplicating the
calling process.
exec - perform the transformation of a process
by overlaying its memory space with a new
program.
wait - provides the ability for a process to be
halted while a related process finishes.
exit - used to terminate a process.
The fork system call
 Usage :
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
 A successful call will result in the creation of a
new process that is more or less identical to the
calling process.
The Process
The newly created process is called as the
child process and the process that made
the call is called as the parent process.
After the system call is made successfully
both processes begin execution at the
statement after the call to fork.
Both processes will have identical data and
code segments. All the variable will have
the same value as before the fork call.
OUTPUT
printf(“one\n”);
pid = fork();
printf(“two\n”);
PC
PC
fork()
$ one
$ two
$ two
Before
After
printf(“one\n”);
pid = fork();
printf(“two\n”);
PC
printf(“one\n”);
pid = fork();
printf(“two\n”);
PC
Process IDs
fork() returns two values, unlike most
system calls.
fork() returns the process id of the newly
created process to the parent.
fork() returns a 0 to the newly created
process.
Since all the variables are common, this
can be used to synchronize and distinguish
the child process from the parent process.
The exec family of calls
• Unlike fork, exec will replace the calling
process.
• fork replicates the calling process, exec
will create a new process and destroys the
called process. The new process will
inherit the process id of the called
process.
• What is the point? What is interesting
about simply the same process over and
over again?
printf (…)
PC
execl(“bin/ls”,…)
PC
Before
exec
After
1st line of ls
PC
Data and File Sharing in fork
• In fork(), an identical copy of the parent
process is made.
• All the variables are identical and all files
open in the parent will remain open in the
child process.
• Since the child process occupies a different
memory location, modifications are local.
• Open files are are however different. The
read-write pointer is maintained by the OS.
Data and File Sharing in exec
• Open file descriptors are also passed across
exec calls.
• The read-write pointer remains in the same
position as in the process that called exec.
• What about variables and their values?
• The system call fcntl can be used to set the
close-on-exec flag. When this flag is set
the file is closed when the exec calls is
made.
#include<fcntl.h>
int fd;
fd = open(“file”, O_RDONLY);
.
/* set close-on-exec flag on */
fcntl(fd, F_SETFD, 1);
/*set close-on-exec flag off */
fcntl (fd, F_SETFD, 0);
/* the value can be obtained as follows */
res = fcntl(fd, F_GETFD, 0);
Terminating a process - exit
• Usage
#include < stdlib.h>
void exit(int status);
Synchronizing Processes - the
wait system call
• Usage
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait (int *status);
wait() temporarily suspends the process till
its child process finishes execution.
More on wait
• The call to wait returns the process id of
the child process that exits
• The argument to wait is an integer pointer
that contains the exit code of the exiting
child process.
• If there are n child processes, n wait
statements would be needed if the parent is
to continue after all the child processes
have exited.
Waiting for a specific child
• Usage
#include<sys/types.h>
#include<sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);
• The first argument specifies the id of the
process the parent is waiting for (if this is
set to -1 and the options to 0, this call
behaves exactly like wait() ).
waitpid system call
• The second argument contains the exit
status of the child.
• The final argument options can take a
variety of values defined in <sys/wait.h>
• The most useful is the option WNOHANG
• This allows waitpid to sit in a loop,
without blocking.
• waitpid returns the process id of the child
process once terminated.
Zombies and premature exits
• A process becomes a zombie when a child
process exits before the parent process
issues a wait.
• This results in the process occupying space
in the system’s process table but nothing
else.
• If a parent process exits before a child
process is done. That process is
“orphaned” and is “adopted” by the OS
(and killed!).
The shell - What it shall do
• Assemble commands and execute them
• Execute in either foreground or
background (command used with &).
• Deal with a line with multiple commands
separated by semicolons.
• I/O redirection (< >) and pipe (|) will be
added later (by you!)
A small Shell program
• A shell is a command interpreter.
• The idea is simple
while( EOF not typed)
{
get command line from user
assemble command args and execute
wait for child
}
Lets define some useful constants
The userin function
• The userin.c will get the command line.
• The program will print a prompt, then
wait for a line of input from the keyboard.
• Any input (read one character at a time) it
receives will be placed in a buffer.
• We shall set a max length for the command
line, the program will also check for any
violations.
The userin.c program
The gettok.c program
• This program extracts individual tokens
from the command line constructed by
userin.
• A token is a lexical unit such as a
command name or argument.
• gettok is invoked as follows:
• toktype = gettok(&tptr);
• toktype is an integer indicating the type of
token, defined in smallsh.h.
gettok.c continued
• tptr is a character pointer that points to the
actual token itself after the call to gettok.
• Note that since it references the character
pointers tok and ptr, it must be included in
the same source file as userin.
• This is why tok and ptr are initialized as
they are in userin.
inarg is used to determine whether a character
can be part of an ‘ordinary’ argument. For the
time being, we need just check whether the
character is special to smallsh or not:
Procline.c program
• procline will parse a command line using
gettok, constructing an argument list in the
process.
• When it encounters a newline or semicolon
it invokes a routine called called
runcommand to execute the command.
• It assumes that an input has already been
read with userin.
runcommand.c
• The next stage is the runcommand function
that actually starts any command
processes.
• The runcommand is very similar to the
docommand seen earlier, except it takes
an additional parameter (where) to indicate
if the process is to be run in foreground or
background.
• The waitpid is also omitted (we’ll see
why).
Now the main function that ties all
these together.