Transcript fork
Process Control
Major Requirements of an
Operating System
Interleave the execution of several
processes to maximize processor
utilization while providing reasonable
response time
Allocate resources to processes
Support interprocess communication and
user creation of processes
Process
A program in execution
Consists of three components
– An executable program
– Associated data needed by the program
– Execution context of the program
All information the operating system needs to
manage the process
UNIX Process States
Process Creation
Submission of a batch job
User logs on
Created to provide a service such as
printing
Process creates another process
Process Creation
A process may create other processes
– parent - child
– process tree
Each process needs resources
– CPU time
– memory
Deciding how to allocate the resources is
a policy that is determined by the OS
Process Creation Decisions
Resource Allocation
– Treat as a new process
– Divide parent’s resources among children
Execution
– child runs concurrently with parent
– parent waits until some or all children
terminate
Address Space
– copy of parent
– new program loaded into address space
Unix process creation
A new process is created by the fork call
Child and parent are identical
– child returns a 0
– parent returns nonzero
Both parent and child execute next line
Often the child executes an exec
– creates a brand new process in its space
Parent can execute a wait
Example: Process Creation in
Unix
int pid;
int status = 0;
pid = fork()
if (pid != 0)
{
/* parent */
…..
pid = wait(&status);
}
else
{
/* child */
…..
exit(status);
}
The fork syscall returns
twice: it returns a zero to
the child and the child
process ID (pid) to the
parent.
Parent uses wait to sleep
until the child exits; wait
returns child pid and status.
Wait variants allow wait on a
specific child, or notification
of stops and other signals.
Wait has the effect of
cleaning up the process out
of the system – removes it
from the zombie state.
Unix Fork/Exec/Exit/Wait
Example
fork parent
fork child
initialize
child
context
exec
int pid = fork();
Create a new process that is a
clone of its parent.
exec*(“program” [, argvp, envp]);
Overlay the calling process virtual
memory with a new program, and
transfer control to it.
exit(status);
Exit with status, destroying the
process.
wait
exit
int pid = wait*(&status);
Wait for exit (or other status change)
of a child.
child1 = fork();
if (child1 == 0)
{
/* I am the child process */
child1P(one2two, two2one);
}
else
{
child2 = fork();
if (child2 == 0)
{
/* I am the child process */
child2P(one2two, two2one);
}
else
{
/* I am the parent */
/* Wait for child one */
waitpid(child1, status1, options);
/* Wait for child two */
waitpid(child2, status2, options);
printf("The children are finally finished\n");
fflush(stdout);
}
}
#include <iostream>
#include <string>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
int globalVariable = 2;
main()
{
string sIdentifier;
int
iStackVariable = 20;
pid_t pID = fork();
if (pID == 0)
// child
{
// Code only executed by child process
sIdentifier = "Child Process: ";
globalVariable++;
iStackVariable++;
}
else if (pID < 0)
// failed to fork
{
cerr << "Failed to fork" << endl;
exit(1);
// Throw exception
}
else
// parent
{
// Code only executed by parent process
sIdentifier = "Parent Process:";
}
// Code
cout <<
cout <<
cout <<
}
executed by both parent and child.
sIdentifier;
" Global variable: " << globalVariable;
" Stack variable: " << iStackVariable << endl;
Potential Pitfalls
Unintended File Sharing
– Child process is a copy of parent
– Includes files and other OS structures
– Intermixed output
– File close on termination
Race conditions
– Each process is scheduled independently
Exec
Fork creates a copy of the parent
Use exec() to launch another program
– Initiate a program from within a program
– Transforms the calling process into a new
process
Family of functions
– execl, execlp, execle, execv, execvp, execvP
– Front ends to the function execve
execve
Executes a process in an environment
which it assigns
Process arguments and the environment
are passed as null terminated arrays of
character pointers
– char *env[] = {“USER=qos”,”PATH=/usr/bin:/bin”, (char *)0 };
– char *args[] = {“/bin/someprog”, “-r”, “-verbose”, (char *)0 };
– execve(args[0], args, env);
execl and execlp
Creates a new program in the same
environment
execl requires a fully qualified path
execlp will use the environment variable
PATH to search for the file
Takes a null terminated list of arguments
execv and execvp
Same as execl
– Arguments are passed as a null terminated
array of character pointers
#include <sys/types.h>
#include <unistd.h>
int pid;
int status = 0;
pid = fork();
if (pid != 0)
{
/* parent */
…..
pid = wait(&status);
}
else
{
/* child */
// Allocate and fill in argv and envp
//execve(const char *filename, char *const argv [], char *const envp[]);
execve(argv[0], argv, envp);
// exec shouldn’t return
return(ERROR);
}
Setting up the environment
// Set up the environment variable array
env = (char **)malloc((headerLines.size() + 1) * sizeof(char *));
for (i = 0; i < headerLines.size(); i++)
{
env[i] = (char *)malloc(headerLength * sizeof(char));
strcpy(env[i], headerLines[i]);
if (strstr(env[i], "CONTENT_LENGTH"))
{
sscanf(env[i], "CONTENT_LENGTH=%d", &contentLength);
//fprintf(stderr, "Scanned CONTENT_LENGTH is %d\n", contentLength);
}
//fprintf(stderr, "Header --> [%s]\n", env[i]);
}
env[i] = NULL;