Unix Process Management in Computer Systems II

undefined
Computer Systems II
Creating and Terminating
Unix Processes
R
e
c
a
p
:
 
C
o
d
e
 
v
s
.
 
E
x
e
c
u
t
a
b
l
e
 
v
s
.
 
P
r
o
c
e
s
s
C source code
C statements organized into functions
Stored as a collection of files (.c and .h)
Executable module
Binary image generated by compiler
Stored as a file (e.g., 
a.out
)
Process
Instance of a program that is executing
Managed by the operating system
Executable
C source code
Process
compiling
running
R
e
c
a
p
:
 
M
e
m
o
r
y
 
L
a
y
o
u
t
 
o
f
 
a
 
U
n
i
x
 
P
r
o
c
e
s
s
0
High Memory Address
Text
Data
BSS
Stack
Heap
 
(machine code)
 
(initialized global variables)
 
(uninitialized global variables)
 
(dynamically allocated memory)
 
(local variables)
H
e
a
p
:
 
D
y
n
a
m
i
c
 
M
e
m
o
r
y
   
#include <stdlib.h>
void *malloc(size_t size);
void free(void *ptr);
0
0xFFFFFFFF
Text
Data
BSS
Stack
H
e
a
p
H
e
a
p
p
1
char *p1 = malloc(3);
char *p2 = malloc(1);
char *p3 = malloc(4);
free(p2);
...
H
e
a
p
:
 
D
y
n
a
m
i
c
 
M
e
m
o
r
y
   
#include <stdlib.h>
void *malloc(size_t size);
void free(void *ptr);
0
0xFFFFFFFF
Text
Data
BSS
Stack
H
e
a
p
H
e
a
p
p
1
char *p1 = malloc(3);
char *p2 = malloc(1);
char *p3 = malloc(4);
free(p2);
...
H
e
a
p
:
 
D
y
n
a
m
i
c
 
M
e
m
o
r
y
   
#include <stdlib.h>
void *malloc(size_t size);
void free(void *ptr);
0
0xFFFFFFFF
Text
Data
BSS
Stack
H
e
a
p
H
e
a
p
p
1
char *p1 = malloc(3);
char *p2 = malloc(1);
char *p3 = malloc(4);
free(p2);
...
H
e
a
p
:
 
D
y
n
a
m
i
c
 
M
e
m
o
r
y
   
#include <stdlib.h>
void *malloc(size_t size);
void free(void *ptr);
0
0xFFFFFFFF
Text
Data
BSS
Stack
H
e
a
p
H
e
a
p
p
1
char *p1 = malloc(3);
char *p2 = malloc(1);
char *p3 = malloc(4);
free(p2);
...
 
No garbage collector!
Everything allocated with 
malloc
must be deallocated with 
free
R
e
c
a
p
:
 
P
r
o
c
e
s
s
 
I
d
e
n
t
i
f
i
e
r
s
Each process in the system has a unique identifier
What does this code print out?
getpid
 
returns the identifier of the calling process
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
 
pid_t myid;
 
 
myid = getpid();
 
printf(“myid = [%d]\n”, myid);
 
return 0;
}
C
r
e
a
t
i
n
g
 
a
 
N
e
w
 
U
n
i
x
 
P
r
o
c
e
s
s
:
 
f
o
r
k
The 
fork
 system call creates a new process in the system
-
Calling process becomes 
Parent
-
New process is its 
Child 
(copy of Parent)
-
Parent and child execute concurrently
Parent
Child
fork()
T
r
e
e
 
o
f
 
U
n
i
x
 
P
r
o
c
e
s
s
e
s
After a successful 
fork
,
both parent and child keep
running, and each can fork
off other processes
The result is a 
Processs Tree
The root of the tree is a
special process created by
the OS during startup
B
o
o
t
i
n
g
When a computer is switched on or reset, there must be
an initial process that gets the system running
This is the boot loader process
Initialize CPU registers, device controllers, memory
Load the OS into memory
Start the OS running
OS starts the first process
OS waits for some event to occur
Hardware interrupts or software interrupts (traps)
T
h
e
 
f
o
r
k
 
S
y
s
t
e
m
 
C
a
l
l
Syntax is
    
pid_t
 
fork(
void
)
;
Sample call:
pid_t ret;
ret = 
fork()
;
Calling process split into two: parent and child
Child is an identical copy of the parent, with one exception:
 
ret =  0 in the child process
 
ret = non-zero value in the parent
ret = -1 if fork is unsuccessful
T
h
e
 
f
o
r
k
 
S
y
s
t
e
m
 
C
a
l
l
 
I
l
l
u
s
t
r
a
t
e
d
ret
 = 
fork()
;
 
ret = -1 if unsuccessful
ret =  0 in the child
ret = the child’s identifier
in the parent process
T
r
y
 
I
t
 
O
u
t
 
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
 
pid_t  ret;
 
pid_t myid;
 
 
/* fork another process */
 
ret = fork();
 
if (ret < 0) { /* error occurred */
  
printf("Fork Failed \n");
  
return 1;
 
}
 
myid = getpid();
 
printf(“ret = [%d], myid = [%d]\n”, ret, myid);
 
 
return 0;
}
T
r
y
 
T
h
i
s
 
O
u
t
 
#include ??? /* what header files are needed? */
 
#include <stdio.h>
int main()
{
 
pid_t  ret;
 
pid_t myid;
 
 
/* fork another process */
 
ret = fork();
 
if (ret < 0) { /* error occurred */
  
printf("Fork Failed \n");
  
return 1;
 
}
 
myid = getpid();
 
printf(“ret = [%d], myid = [%d]\n”, ret, myid);
 
 
return 0;
}
f
o
r
k
:
 
P
a
r
e
n
t
 
a
n
d
 
C
h
i
l
d
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
 
How 
fork
 Works (1)
Text
Stack
Data
File
Resources
pid = 25
r
e
t
 
=
 
f
o
r
k
(
)
;
s
w
i
t
c
h
(
r
e
t
)
{
 
 
 
 
c
a
s
e
 
-
1
:
 
 
 
 
 
p
r
i
n
t
f
(
f
o
r
k
 
e
r
r
o
r
)
;
e
x
i
t
(
1
)
;
 
 
 
 
 
c
a
s
e
 
0
:
 
 
/
/
 
I
 
a
m
 
t
h
e
 
c
h
i
l
d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<
c
o
d
e
 
f
o
r
 
c
h
i
l
d
 
>
e
x
i
t
(
0
)
;
 
 
 
 
 
d
e
f
a
u
l
t
:
 
 
/
/
 
I
 
a
m
 
p
a
r
e
n
t
 
.
.
.
 
 
<
c
o
d
e
 
f
o
r
 
p
a
r
e
n
t
 
>
w
a
i
t
(
0
)
;
}
PCB
UNIX
 
How 
fork
 Works (2)
Text
PCB
Stack
Data
File
Resources
pid = 25
r
e
t
 
=
 
f
o
r
k
(
)
;
s
w
i
t
c
h
(
r
e
t
)
{
 
 
 
 
c
a
s
e
 
-
1
:
 
 
 
 
 
p
r
i
n
t
f
(
f
o
r
k
 
e
r
r
o
r
)
;
e
x
i
t
(
1
)
;
 
 
 
 
 
c
a
s
e
 
0
:
 
 
/
/
 
I
 
a
m
 
t
h
e
 
c
h
i
l
d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<
c
o
d
e
 
f
o
r
 
c
h
i
l
d
 
>
e
x
i
t
(
0
)
;
 
 
 
 
 
d
e
f
a
u
l
t
:
 
 
/
/
 
I
 
a
m
 
p
a
r
e
n
t
 
.
.
.
 
 
<
c
o
d
e
 
f
o
r
 
p
a
r
e
n
t
 
>
w
a
i
t
(
0
)
;
}
UNIX
ret = 26
 
How 
fork
 Works (3)
Text
PCB
Stack
Data
File
Resources
pid = 25
Text
PCB
Stack
Data
pid = 26
r
e
t
 
=
 
f
o
r
k
(
)
;
s
w
i
t
c
h
(
r
e
t
)
{
 
 
 
 
c
a
s
e
 
-
1
:
 
 
 
 
 
p
r
i
n
t
f
(
f
o
r
k
 
e
r
r
o
r
)
;
e
x
i
t
(
1
)
;
 
 
 
 
 
c
a
s
e
 
0
:
 
 
/
/
 
I
 
a
m
 
t
h
e
 
c
h
i
l
d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<
c
o
d
e
 
f
o
r
 
c
h
i
l
d
 
>
e
x
i
t
(
0
)
;
 
 
 
 
 
d
e
f
a
u
l
t
:
 
 
/
/
 
I
 
a
m
 
p
a
r
e
n
t
 
.
.
.
 
 
<
c
o
d
e
 
f
o
r
 
p
a
r
e
n
t
 
>
w
a
i
t
(
0
)
;
}
r
e
t
 
=
 
f
o
r
k
(
)
;
s
w
i
t
c
h
(
r
e
t
)
{
 
 
 
 
c
a
s
e
 
-
1
:
 
 
 
 
 
p
r
i
n
t
f
(
f
o
r
k
 
e
r
r
o
r
)
;
e
x
i
t
(
1
)
;
 
 
 
 
 
c
a
s
e
 
0
:
 
 
/
/
 
I
 
a
m
 
t
h
e
 
c
h
i
l
d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<
c
o
d
e
 
f
o
r
 
c
h
i
l
d
 
>
e
x
i
t
(
0
)
;
 
 
 
 
 
d
e
f
a
u
l
t
:
 
 
/
/
 
I
 
a
m
 
p
a
r
e
n
t
 
.
.
.
 
 
<
c
o
d
e
 
f
o
r
 
p
a
r
e
n
t
 
>
w
a
i
t
(
0
)
;
}
UNIX
ret = 26
ret = 0
 
How 
wait
 Works
r
e
t
 
=
 
f
o
r
k
(
)
;
s
w
i
t
c
h
(
r
e
t
)
{
 
 
 
 
c
a
s
e
 
-
1
:
 
 
 
 
 
p
r
i
n
t
f
(
f
o
r
k
 
e
r
r
o
r
)
;
e
x
i
t
(
1
)
;
 
 
 
 
 
c
a
s
e
 
0
:
 
 
/
/
 
I
 
a
m
 
t
h
e
 
c
h
i
l
d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<
c
o
d
e
 
f
o
r
 
c
h
i
l
d
 
>
e
x
i
t
(
0
)
;
 
 
 
 
 
d
e
f
a
u
l
t
:
 
 
/
/
 
I
 
a
m
 
p
a
r
e
n
t
 
.
.
.
 
 
<
c
o
d
e
 
f
o
r
 
p
a
r
e
n
t
 
>
w
a
i
t
(
0
)
;
}
r
e
t
 
=
 
f
o
r
k
(
)
;
s
w
i
t
c
h
(
r
e
t
)
{
 
 
 
 
c
a
s
e
 
-
1
:
 
 
 
 
 
p
r
i
n
t
f
(
f
o
r
k
 
e
r
r
o
r
)
;
e
x
i
t
(
1
)
;
 
 
 
 
 
c
a
s
e
 
0
:
 
 
/
/
 
I
 
a
m
 
t
h
e
 
c
h
i
l
d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<
c
o
d
e
 
f
o
r
 
c
h
i
l
d
 
>
e
x
i
t
(
0
)
;
 
 
 
 
 
d
e
f
a
u
l
t
:
 
 
/
/
 
I
 
a
m
 
p
a
r
e
n
t
 
.
.
.
 
 
<
c
o
d
e
 
f
o
r
 
p
a
r
e
n
t
 
>
w
a
i
t
(
0
)
;
}
UNIX
Parent blocked
Parent blocks until child terminates
-
If the parent has multiple children, one 
wait
 
call causes parent to
wait for only one arbitrary child
-
If the parent must wait for all children, it needs to invoke 
multiple
wait
 calls (one per child)
r
e
t
 
=
 
f
o
r
k
(
)
;
s
w
i
t
c
h
(
r
e
t
)
{
 
 
 
 
c
a
s
e
 
-
1
:
 
 
 
 
 
p
r
i
n
t
f
(
f
o
r
k
 
e
r
r
o
r
)
;
e
x
i
t
(
1
)
;
 
 
 
 
 
c
a
s
e
 
0
:
 
 
/
/
 
I
 
a
m
 
t
h
e
 
c
h
i
l
d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<
c
o
d
e
 
f
o
r
 
c
h
i
l
d
 
>
e
x
i
t
(
0
)
;
 
 
 
 
 
d
e
f
a
u
l
t
:
 
 
/
/
 
I
 
a
m
 
p
a
r
e
n
t
 
.
.
.
 
 
<
c
o
d
e
 
f
o
r
 
p
a
r
e
n
t
 
>
w
a
i
t
(
0
)
;
}
 
How 
exit
 Works
r
e
t
 
=
 
f
o
r
k
(
)
;
s
w
i
t
c
h
(
r
e
t
)
{
 
 
 
 
c
a
s
e
 
-
1
:
 
 
 
 
 
p
r
i
n
t
f
(
f
o
r
k
 
e
r
r
o
r
)
;
e
x
i
t
(
1
)
;
 
 
 
 
 
c
a
s
e
 
0
:
 
 
/
/
 
I
 
a
m
 
t
h
e
 
c
h
i
l
d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<
c
o
d
e
 
f
o
r
 
c
h
i
l
d
 
>
e
x
i
t
(
0
)
;
 
 
 
 
 
d
e
f
a
u
l
t
:
 
 
/
/
 
I
 
a
m
 
p
a
r
e
n
t
 
.
.
.
 
 
<
c
o
d
e
 
f
o
r
 
p
a
r
e
n
t
 
>
w
a
i
t
(
0
)
;
}
UNIX
ret = 26
ret = 0
When the child terminates 
 say, by calling 
exit
 
 the
operating system sends a signal to unblock the parent
-
Parent is now ready to complete its execution
 
Parent unblocked
 
How 
fork
 Works (6)
Text
Stack
Data
File
Resources
pid = 25
r
e
t
 
=
 
f
o
r
k
(
)
;
s
w
i
t
c
h
(
r
e
t
)
{
 
 
 
 
c
a
s
e
 
-
1
:
 
 
 
 
 
p
r
i
n
t
f
(
f
o
r
k
 
e
r
r
o
r
)
;
e
x
i
t
(
1
)
;
 
 
 
 
 
c
a
s
e
 
0
:
 
 
/
/
 
I
 
a
m
 
t
h
e
 
c
h
i
l
d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
<
c
o
d
e
 
f
o
r
 
c
h
i
l
d
 
>
e
x
i
t
(
0
)
;
 
 
 
 
 
d
e
f
a
u
l
t
:
 
 
/
/
 
I
 
a
m
 
p
a
r
e
n
t
 
.
.
.
 
 
<
c
o
d
e
 
f
o
r
 
p
a
r
e
n
t
 
>
w
a
i
t
(
0
)
;
<
 
 
>
ret = 26
PCB
Parent
 ready to
complete execution
23
O
r
d
e
r
l
y
 
T
e
r
m
i
n
a
t
i
o
n
:
 
e
x
i
t
(
)
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)
R
e
c
a
p
:
 
M
a
n
a
g
i
n
g
 
U
n
i
x
 
P
r
o
c
e
s
s
e
s
List processes using the 
ps
 (process status) ommand:
ps -f
The first column of the result is the process identifier
To force a process to finish executing, use kill:
  
kill –s KILL 
processid
    (or)
 
kill –SIGKILL 
processid
 
   
(or)
 
kill –9 
processid
F
o
r
k
 
E
x
a
m
p
l
e
 
1
:
 
W
h
a
t
 
O
u
t
p
u
t
?
int x = 5;
int main()
{ 
   pid_t ret;
 
   ret = fork();
   
if (ret != 0) {
     printf(
parent: x = %d\n
, --x);
     exit(0);
   
}
 
else {
     printf(
child: x = %d\n
, ++x);
     exit(0);
   }
}
F
o
r
k
 
E
x
a
m
p
l
e
 
2
Both parent and child continue forking:
void fork2()
{
    printf("L0\n");
    fork();
    
printf("L1\n");
    
    fork();
    
printf("Bye\n");
}
P
 
L0
 
L1
 
L1
 
Bye
 
Bye
 
Bye
 
Bye
F
o
r
k
 
E
x
a
m
p
l
e
 
3
void fork3()
{
    printf("L0\n");
    fork();
    
printf("L1\n");    
    fork();
    
printf("L2\n");    
    fork();
    
printf("Bye\n")
;
}
P
L0
L1
L1
L2
L2
L2
L2
 
Bye
 
Bye
 
Bye
 
Bye
 
Bye
 
Bye
 
Bye
 
Bye
Both parent and child continue forking:
F
o
r
k
 
E
x
a
m
p
l
e
 
4
void fork4()
{
    int ret;
    printf("L0\n");
    ret = fork();
    if (
ret
 != 0) {
 
printf("L1\n"); 
 
 
ret = fork();
 
  
 
if (
ret
 != 0) {
 
   
 printf("L2\n");
 
    fork();
 
}
    }
   
 printf("Bye\n");
}
P
 
L0
 
L1
 
Bye
 
Bye
 
Bye
 
Bye
 
L2
Only the parent continues forking:
F
o
r
k
 
E
x
a
m
p
l
e
 
5
void fork5()
{
    int ret;
    printf("L0\n");
    ret = fork();
    if (
ret
 == 0) {
 
printf("L1\n"); 
 
 
ret = fork();
   
 
if (
ret
 == 0) {
 
    
printf("L2\n");
 
    fork();
 
}
    }
   
 printf("Bye\n");
}
P
 
L0
 
L1
 
Bye
 
Bye
 
Bye
 
L2
 
Bye
Only the child continues forking:
H
a
n
d
s
 
O
n
 
Write a C program that does the following:
Takes a list of file names from the command line
 
For each file in the list:
Parent prints out the filename, forks child, waits for child
 
 
 
Child displays the contents of the file (use 
tail
)
 
 
readme
 
invoke 
system(
tail readme
)
 
./a.out readme code.cpp game.input
 
code.cpp
 
invoke 
system(
tail code.cpp
)
 
game.input
 
invoke 
system(
tail game.input
)
H
a
n
d
s
 
O
n
 
(
c
o
n
t
d
.
)
After all children finished executing, the parent prints
out
 
  
 
N files processed, done!
        where N is the number of filenames in the
        command line.
R
e
c
a
p
fork
creates a duplicate of the calling process
returns 0 to the child, and child identifier to the parent
returns -1 in case of failure
wait
invoked by parent
parent blocks until one (arbitrary) child terminates
exit
terminates the calling process
Slide Note
Embed
Share

This overview delves into the creation, termination, memory layout, and dynamic memory management of Unix processes in Computer Systems II. It covers the distinctions between code, executables, and processes, the memory layout of Unix processes, management of heap memory using malloc and free functions, and the importance of process identifiers. The content provides a comprehensive understanding of how Unix processes function and the essential concepts related to their management.

  • Unix Processes
  • Memory Layout
  • Dynamic Memory Management
  • Code Execution
  • Process Identifiers

Uploaded on Oct 07, 2024 | 0 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.

E N D

Presentation Transcript


  1. Computer Systems II Creating and Terminating Unix Processes

  2. Recap: Code vs. Executable vs. Process C source code C statements organized into functions Stored as a collection of files (.c and .h) C source code Executable module Binary image generated by compiler Stored as a file (e.g., a.out) compiling Executable Process Instance of a program that is executing Managed by the operating system running Process

  3. Recap: Memory Layout of a Unix Process 0 (machine code) Text (initialized global variables) Data (uninitialized global variables) BSS (dynamically allocated memory) Heap Stack (local variables) High Memory Address

  4. Heap: Dynamic Memory #include <stdlib.h> void *malloc(size_t size); void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); ... Data BSS Heap Stack 0xFFFFFFFF

  5. Heap: Dynamic Memory #include <stdlib.h> void *malloc(size_t size); void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); ... Data p2 BSS Heap Stack 0xFFFFFFFF

  6. Heap: Dynamic Memory #include <stdlib.h> void *malloc(size_t size); void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); ... Data p2 p3 BSS Heap Stack 0xFFFFFFFF

  7. Heap: Dynamic Memory #include <stdlib.h> void *malloc(size_t size); void free(void *ptr); 0 Text Heap p1 char *p1 = malloc(3); char *p2 = malloc(1); char *p3 = malloc(4); free(p2); ... Data BSS p3 Heap No garbage collector! Everything allocated with malloc must be deallocated with free Stack 0xFFFFFFFF

  8. Recap: Process Identifiers Each process in the system has a unique identifier What does this code print out? #include <sys/types.h> #include <unistd.h> #include <stdio.h> int main() { pid_t myid; myid = getpid(); printf( myid = [%d]\n , myid); return 0; } getpid returns the identifier of the calling process

  9. Creating a New Unix Process: fork The fork system call creates a new process in the system - Calling process becomes Parent - New process is its Child (copy of Parent) - Parent and child execute concurrently Parent fork() Child

  10. Tree of Unix Processes After a successful fork, both parent and child keep running, and each can fork off other processes The result is a Processs Tree The root of the tree is a special process created by the OS during startup

  11. The fork System Call Syntax is pid_t fork(void); Sample call: pid_t ret; ret = fork(); Calling process split into two: parent and child Child is an identical copy of the parent, with one exception: ret = 0 in the child process ret = non-zero value in the parent ret = -1 if fork is unsuccessful

  12. The fork System Call Illustrated fork() ret = fork(); ret = -1 if unsuccessful Text Text Data Data ret = 0 in the child Heap Heap ret = the child s identifier in the parent process ret = 0 Stack Stack ret = xxx Parent Child

  13. Try This Out #include ??? /* what header files are needed? */ #include <stdio.h> int main() { pid_t ret; pid_t myid; /* fork another process */ ret = fork(); if (ret < 0) { /* error occurred */ printf("Fork Failed \n"); return 1; } myid = getpid(); printf( ret = [%d], myid = [%d]\n , ret, myid); return 0; }

  14. fork: Parent and Child 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

  15. How fork Works (1) pid = 25 Data Resources Text Stack PCB File ret = fork(); switch(ret) { case -1: case 0: // I am the child <code for child > exit(0); default: // I am parent ... <code for parent > wait(0); } printf( fork error ); exit(1); UNIX

  16. How fork Works (2) pid = 25 pid = 26 Data Data Resources Text Text Stack Stack PCB PCB File ret = 0 ret = fork(); switch(ret) { case -1: case 0: // I am the child <code for child > exit(0); default: // I am parent ... <code for parent > wait(0); } ret = 26 ret = fork(); switch(ret) { case -1: case 0: // I am the child <code for child > exit(0); default: // I am parent ... <code for parent > wait(0); } printf( fork error ); exit(1); printf( fork error ); exit(1); UNIX

  17. How fork Works (3) pid = 25 pid = 26 Data Data Resources Text Text Stack Stack PCB PCB File ret = 0 ret = fork(); switch(ret) { case -1: case 0: // I am the child <code for child > exit(0); default: // I am parent ... <code for parent > wait(0); } ret = 26 ret = fork(); switch(ret) { case -1: case 0: // I am the child <code for child > exit(0); default: // I am parent ... <code for parent > wait(0); } printf( fork error ); exit(1); printf( fork error ); exit(1); UNIX

  18. How wait Works Parent blocks until child terminates - If the parent has multiple children, one wait call causes parent to wait for only one arbitrary child - If the parent must wait for all children, it needs to invoke multiple wait calls (one per child) ret = fork(); switch(ret) { case -1: case 0: // I am the child <code for child > exit(0); default: // I am parent ... <code for parent > wait(0); } ret = fork(); switch(ret) { case -1: case 0: // I am the child <code for child > exit(0); default: // I am parent ... <code for parent > wait(0); } printf( fork error ); exit(1); printf( fork error ); exit(1); Parent blocked UNIX

  19. How exit Works When the child terminates say, by calling exit the operating system sends a signal to unblock the parent - Parent is now ready to complete its execution ret = 0 ret = fork(); switch(ret) { case -1: case 0: // I am the child <code for child > exit(0); default: // I am parent ... <code for parent > wait(0); } ret = 26 ret = fork(); switch(ret) { case -1: case 0: // I am the child <code for child > exit(0); default: // I am parent ... <code for parent > wait(0); } printf( fork error ); exit(1); printf( fork error ); exit(1); Parent unblocked UNIX

  20. How fork Works (6) pid = 25 Data Resources Text Stack PCB File ret = 26 ret = fork(); switch(ret) { case -1: case 0: // I am the child <code for child > exit(0); default: // I am parent ... <code for parent > wait(0); < > Parent ready to complete execution printf( fork error ); exit(1);

  21. Recap: Managing Unix Processes List processes using the ps (process status) ommand: ps -f The first column of the result is the process identifier To force a process to finish executing, use kill: kill s KILL processid (or) kill SIGKILL processid (or) kill 9 processid

  22. Fork Example 1: What Output? int x = 5; int main() { pid_t ret; ret = fork(); if (ret != 0) { printf( parent: x = %d\n , --x); exit(0); } else { printf( child: x = %d\n , ++x); exit(0); } }

  23. Fork Example 2 Both parent and child continue forking: L0 L1 Bye P void fork2() { printf("L0\n"); fork(); printf("L1\n"); fork(); printf("Bye\n"); } L1 Bye C1 C2 Bye C3 Bye

  24. Fork Example 3 Both parent and child continue forking: L0 L1 L2 Bye P void fork3() { printf("L0\n"); fork(); printf("L1\n"); fork(); printf("L2\n"); fork(); printf("Bye\n"); } L1 L2 Bye L2 Bye C1 C2 C4 Bye L2 Bye C6 C5 C3 Bye Bye C7 Bye

  25. Fork Example 4 Only the parent continues forking: L0 L1 L2 void fork4() { int ret; P Bye printf("L0\n"); ret = fork(); if (ret != 0) { printf("L1\n"); ret = fork(); if (ret != 0) { printf("L2\n"); fork(); } } printf("Bye\n"); } C1 C2 C3 Bye Bye Bye

  26. Fork Example 5 Only the child continues forking: void fork5() { int ret; L0 Bye P printf("L0\n"); ret = fork(); if (ret == 0) { printf("L1\n"); ret = fork(); if (ret == 0) { printf("L2\n"); fork(); } } printf("Bye\n"); } C1 L1 Bye C2 L2 Bye C3 Bye

  27. Recap fork creates a duplicate of the calling process returns 0 to the child, and child identifier to the parent returns -1 in case of failure wait invoked by parent parent blocks until one (arbitrary) child terminates exit terminates the calling process

More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#