[go: up one dir, main page]

0% found this document useful (0 votes)
194 views37 pages

Fork

The document discusses process creation in Unix systems. A process can create a child process using the fork() system call, which duplicates the calling process. The child process is an exact duplicate of the parent process. After fork(), the parent and child processes run concurrently. A process can wait for its child processes to terminate using the wait() system call.

Uploaded by

adarsh awasthi
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)
194 views37 pages

Fork

The document discusses process creation in Unix systems. A process can create a child process using the fork() system call, which duplicates the calling process. The child process is an exact duplicate of the parent process. After fork(), the parent and child processes run concurrently. A process can wait for its child processes to terminate using the wait() system call.

Uploaded by

adarsh awasthi
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/ 37

Programming Tools II (System Calls)

Creating and Executing Processes

Motilal Nehru National Institute of Technology Allahabad,


Prayagraj
1
Unix system calls

fork( )
wait( )
exit( )

2
How To Create New Processes?

Underlying mechanism
- A process runs fork to create a child process
- Parent and children execute concurrently
- Child process is a duplicate of the parent process

parent

fork()

child

3
Process Creation

After a fork, both parent and child keep running, and each can
fork off other processes.

A process tree results. The root of the tree is a special process
created by the OS during startup.


A process can choose to wait for
children to terminate. For
example, if C issued a wait()
system call, it would block until
G finished.

4
Bootstrapping

When a computer is switched on or reset, there must be an
initial program that gets the system running

This is the bootstrap program
- Initialize CPU registers, device controllers, memory
- Load the OS into memory
- Start the OS running


OS starts the first process (such as “init”)

OS waits for some event to occur
- Hardware interrupts or software interrupts (traps)

5
Fork System Call

Current process split into 2 processes: parent, child

Returns -1 if unsuccessful fork()


Returns 0 in the child
Stack Stack

Returns the child’s
identifier in the parent
ret = 0

Data Data
Text ret = xxx Text

6
Fork System Call

The child process inherits from parent
- identical copy of memory
- CPU registers
- all files that have been opened by the parent


Execution proceeds concurrently with the instruction following
the fork system call


The execution context (PCB) for the child process is a copy of the
parent’s context at the time of the call

7
How fork Works (1)
pid = 25

Data Resources
Text
Stack
PCB File

ret = fork();
switch(ret)
{
case -1:
perror(“fork”);
exit(1);
case 0: // I am the child
<code for child >
exit(0);
default: // I am parent ...
UNIX
<code for parent >
wait(0);
}
8
How fork Works (2)
pid = 25 pid = 26

Data Resources Data


Text Text
Stack Stack
PCB File PCB

ret = 26 ret = fork(); ret = 0


ret = fork();
switch(ret) switch(ret)
{ {
case -1: case -1:
perror(“fork”); perror(“fork”);
exit(1); exit(1);
case 0: // I am the child case 0: // I am the child
<code for child > <code for child >
exit(0); exit(0);
default: // I am parent ... default: // I am parent ...
<code for parent > UNIX <code for parent >
wait(0); wait(0);
} }

9
How fork Works (3)
pid = 25 pid = 26

Data Resources Data


Text Text
Stack Stack
PCB File PCB

ret = 26 ret = fork(); ret = 0


ret = fork();
switch(ret) switch(ret)
{ {
case -1: case -1:
perror(“fork”); perror(“fork”);
exit(1); exit(1);
case 0: // I am the child case 0: // I am the child
<code for child > <code for child >
exit(0); exit(0);
default: // I am parent ... default: // I am parent ...
<code for parent > UNIX <code for parent >
wait(0); wait(0);
} }

10
How fork Works (4)
pid = 25 pid = 26

Data Resources Data


Text Text
Stack Stack
PCB File PCB

ret = 26 ret = fork(); ret = 0


ret = fork();
switch(ret) switch(ret)
{ {
case -1: case -1:
perror(“fork”); perror(“fork”);
exit(1); exit(1);
case 0: // I am the child case 0: // I am the child
<code for child > <code for child >
exit(0); exit(0);
default: // I am parent ... default: // I am parent ...
<code for parent > UNIX <code for parent >
wait(0); wait(0);
} }

11
How fork Works (5)
pid = 25 pid = 26

Data Resources Data


Text Text
Stack Stack
PCB File PCB

ret = 26 ret = fork(); ret = 0


ret = fork();
switch(ret) switch(ret)
{ {
case -1: case -1:
perror(“fork”); perror(“fork”);
exit(1); exit(1);
case 0: // I am the child case 0: // I am the child
<code for child > <code for child >
exit(0); exit(0);
default: // I am parent ... default: // I am parent ...
<code for parent > UNIX <code for parent >
wait(0); wait(0);
} }

12
How fork Works (6)
pid = 25

Data Resources
Text
Stack
Process Status File

ret = fork(); ret = 26


switch(ret)
{
case -1:
perror(“fork”);
exit(1);
case 0: // I am the child
<code for child >
exit(0);
default: // I am parent ...
<code for parent > UNIX
wait(0);
<…>
13
Orderly Termination: exit()

To finish execution, a child may call exit(number)

This system call:
- Saves result = argument of exit
- Closes all open files, connections
- Deallocates memory
- Checks if parent is alive
- If parent is alive, holds the result value until the parent requests
it (with wait); in this case, the child process does not really die,
but it enters a zombie/defunct state
- If parent is not alive, the child terminates (dies)

14
Waiting for the Child to Finish

Parent may want to wait for children to finish
- Example: a shell waiting for operations to complete

Waiting for any some child to terminate: wait()
- Blocks until some child terminates
- Returns the process ID of the child process
- Or returns -1 if no children exist (i.e., already exited)

Waiting for a specific child to terminate: waitpid()
- Blocks till a child with particular process ID terminates
#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *status);


pid_t waitpid(pid_t pid, int *status, int options);
15
State Transition on wait and exit Calls

16
Other useful system calls: getpid, getppid

getpid returns the identifier of the calling process. Example
call (pid is an integer):
pid = getpid();

getppid returns the identifier of the parent.

Note:
- Zombies can be noticed by running the 'ps' command (shows the
process list); you will see the string "<defunct>" as their
command name:

ps -ef
ps –ef | grep mdamian

17
Fork Example 1: What Output?

int main()
{
pid_t pid;
int x = 1;

pid = fork();
if (pid != 0) {
printf(“parent: x = %d\n”, --x);
exit(0);
} else {
printf(“child: x = %d\n”, ++x);
exit(0);
}
}
18
Fork Example 2

Key Points
- Both parent and child can continue forking

void fork2()
{
printf("L0\n"); Bye
fork();
L1 Bye
printf("L1\n");
fork(); Bye
printf("Bye\n"); L0 L1 Bye
}

19
Fork Example 3

void fork3() Bye


{
L2 Bye
printf("L0\n");
fork(); Bye
printf("L1\n"); L1 L2 Bye
fork(); Bye
printf("L2\n"); L2 Bye
fork();
printf("Bye\n"); Bye
} L0 L1 L2 Bye

20
Fork Example 4

void fork4()
{
printf("L0\n");
if (fork() != 0) {
printf("L1\n");
if (fork() != 0) {
printf("L2\n");
fork();
}
}
printf("Bye\n");
}

21
Fork Example 5

void fork5()
{
printf("L0\n");
if (fork() == 0) {
printf("L1\n");
if (fork() == 0) {
printf("L2\n");
fork();
}
}
printf("Bye\n");
}

22
Summary

Fork
- Creates a duplicate of the calling process
- The result is two processes: parent and child
- Both continue executing from the same point on

Exit
- Orderly program termination
- Unblocks waiting parent

Wait
- Used by parent
- Waits for child to finish execution
23
Unix system calls
execv
execl

24
Unix’s execv

The system call execv executes a file, transforming the
calling process into a new process. After a successful execv,
there is no return to the calling process.

execv(const char * path, char * const argv[])

 path is the full path for the file to be executed


 argv is the array of arguments for the program to execute

each argument is a null-terminated string

the first argument is the name of the program

the last entry in argv is NULL

25
How execv Works (1)
pid = 25 pid = 26

Data Resources Data


Text Text
Stack Stack
PCB File PCB

char * argv[ ] = {“/bin/ls”, 0}; cpid = 26 cpid = 0 char * argv[ ] = {“/bin/ls”, 0};
<…> <…>
int cpid = fork( ); int cpid = fork( );
if (cpid = = 0) { if (cpid = = 0) {
execv(argv[0], argv); execv(argv[0], argv);
exit(0); exit(0);
} }
<parent code> <parent code>
wait(&cpid); wait(&cpid);

/bin/ls UNIX kernel

26
How execv Works (2)
pid = 25 pid = 26

Data Resources
Text
Stack
PCB File

char * argv[ ] = {“/bin/ls”, 0}; cpid = 26


<…> Exec destroys the
int cpid = fork( );
if (cpid = = 0) {
process image of the
execv(argv[0], argv); calling process. A new
exit(0); process image is
}
<parent code> constructed from the
wait(&cpid); executable file (ls).

/bin/ls UNIX kernel

27
How execv Works (3)
pid = 25 pid = 26

Data Resources Data


Text Text
Stack Stack
PCB File PCB

char * argv[ ] = {“/bin/ls”, 0}; cpid = 26


<first line of ls>
<…>
int cpid = fork( ); <…>
if (cpid = = 0) { <…>
execv(argv[0], argv); <…>
exit(0); exit(0);
}
<parent code>
wait(&cpid);

/bin/ls UNIX kernel

28
Example: A Simple Shell

Shell is the parent process
- E.g., bash bash

Parses command line
- E.g., “ls –l”

Invokes child process fork
- Fork, execvp

Waits for child
- Wait execvp wait

ls

29
execv Example
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

char * argv[] = {“/bin/ls”, “-l”, 0};


int main()
{
int pid, status; Note the NULL string
if ( (pid = fork() ) < 0 ) at the end
{
printf(“Fork error \n”);
exit(1);
}
if(pid == 0) { /* Child executes here */
execv(argv[0], argv);
printf(“Exec error \n”);
exit(1);
} else /* Parent executes here */
wait(&status);
printf("Hello there! \n”);
return 0;
}
30
execv Example – Sample Output

Sample output:

total 282
drwxr-xr-x 2 mdamian faculty 512 Jan 29 14:02 assignments
-rw-r--r-- 1 mdamian faculty 3404 Jan 29 14:05 index.html
drwxr-xr-x 2 mdamian faculty 512 Jan 28 15:02 notes

Hello there!

31
execl

Same as execv, but takes the arguments of the new program as
a list, not a vector:


Example:
execl(“/bin/ls”, “/bin/ls”, “-l”, 0);


Is equivalent to Note the NULL string at the end

char * argv[] = {“/bin/ls”, “-l”, 0};


execv(argv[0], argv);


execl is mainly used when the number of arguments is known
in advance
32
General purpose process creation

In the parent process:
int childPid;
char * const argv[ ] = {…};

main {
childPid = fork();
if(childPid == 0)
{
// I am child ...
// Do some cleaning, close files
execv(argv[0], argv);
}
else
{
// I am parent ...
<code for parent process>
wait(0);
}
}

33
Combined fork/exec/wait

Common combination of operations
- Fork to create a new child process
- Exec to invoke new program in child process
- Wait in the parent process for the child to complete

Single call that combines all three
- int system(const char *cmd);

Example

int main()
{
system(“echo Hello world”);
}

34
Properties of fork / exec sequence

In 99% of the time, we call execv(…) after fork()
- the memory copying during fork() is useless
- the child process will likely close open files and connections
- overhead is therefore high
- might as well combine both in one call (OS/2)


vfork()
- a system call that creates a process without creating an identical
memory image
- sometimes called “lightweight” fork
- child process is understood to call execv() almost immediately

35
Variations of execv

execv
- Program arguments passed as an array of strings

execvp
- Extension of execv
- Searches for the program name in the PATH environment

execl
- Program arguments passed directly as a list

execlp
- Extension of execl
- Searches for the program name in the PATH environment

36
Summary

exec(v,vp,l,lp)
- Does NOT create a new process
- Loads a new program in the image of the calling process
- The first argument is the program name (or full path)
- Program arguments are passed as a vector (v,vp) or list (l,lp)
- Commonly called by a forked child


system:
- combines fork, wait, and exec all in one

37

You might also like