Proceso S
Proceso S
Introduction
What is a process? It’s an illusion!
Process 1
Memory
Stack
Heap
Data
Code
CPU
Registers %rip
Disk
Chrome.exe
What is a process?
Another abstraction in our computer system
Provided by the OS
OS uses a data structure to represent each process
Maintains the interface between the program and the
underlying hardware (CPU + memory)
What do processes have to do with exceptional control
flow?
Exceptional control flow is the mechanism the OS uses to
enable multiple processes to run on the same system
What is the difference between:
A processor? A program? A process?
Processes
A process is an instance of a running program
One of the most profound ideas in computer science
Not the same as “program” or “processor”
Process provides each program with two key
Memory
abstractions:
Logical control flow Stack
• Each program seems to have exclusive use of the CPU Heap
Data
• Provided by kernel mechanism called context switching Code
Private address space
• Each program seems to have exclusive use of main memory CPU
• Provided by kernel mechanism called virtual memory Registers
What is a process? It’s an illusion!
Computer
Process 3
“Memory”
Process 2 Stack
Heap
“Memory” Data
Code Process 4
Stack
Heap
Process 1
Data “CPU” “Memory”
Code
“Memory” Registers
Stack Stack
Heap Heap
“CPU” Data
Data
Registers Code
Code
“CPU” “CPU”
Registers
Registers
CPU
Disk
/Applications/
Chrome.exe Slack.exe PowerPoint.exe
What is a process? It’s an illusion!
Computer
Process 3
“Memory”
Process 2 Stack
Heap
“Memory” Data
Code Process 4
Stack
Heap
Process 1
Data “CPU” “Memory”
Code
“Memory” Registers
Stack Stack
Heap Heap
“CPU” Data
Data
Registers Code
Code
“CPU” “CPU”
Registers
Registers
Operating
System
CPU
Disk
/Applications/
Chrome.exe Slack.exe PowerPoint.exe
Multiprocessing: The Illusion
Memory Memory Memory
CPU
Registers
CPU
Registers
Context switch
1) Save current registers in memory
Multiprocessing
Memory
Stack Stack Stack
Heap Heap Heap
Data Data … Data
Code Code Code
Saved Saved Saved
registers registers registers
CPU
Registers
Context switch
1) Save current registers in memory
2) Schedule next process for execution
Multiprocessing
Memory
Stack Stack Stack
Heap Heap Heap
Data Data … Data
Code Code Code
Saved Saved Saved
registers registers registers
CPU
Registers
Context switch
1) Save current registers in memory
2) Schedule next process for execution
3) Load saved registers and switch address space
Multiprocessing: The (Modern) Reality
Memory
Stack Stack Stack
Heap Heap Heap
Data Data … Data
Code Code Code
Saved Saved Saved
registers registers registers
time
Assume only one CPU
User’s View of Concurrency
Control flows for concurrent processes are physically
disjoint in time
CPU only executes instructions for one process at a time
User View
tim
e
Assume only one CPU
Context Switching
Processes are managed by a shared chunk of OS code
called the kernel
The kernel is not a separate process, but rather runs as part of a user
process
In x86-64 Linux:
Same address in each process
refers to same shared
memory location
Assume only one CPU
Context Switching
Processes are managed by a shared chunk of OS code
called the kernel
The kernel is not a separate process, but rather runs as part of a user
process
Context switch passes control flow from one process to
another and is performed using kernel code
Process A Process B
user code
Excep
tio n kernel code context switch
time
user code
user code
Processes
Processes and context switching
Creating new processes
fork() , exec*(), and wait()
Zombies
Creating New Processes & Programs
Process 1 Process 2
“Memory” “Memory”
Stack Stack
Heap fork() Heap
Data Data
Code Code
“CPU” “CPU”
Registers Registers
exec*()
Chrome.exe
Creating New Processes & Programs
fork-exec model (Linux):
fork() creates a copy of the current process
exec*() replaces the current process’ code and address
space with the code for a different program
• Family: execv, execl, execve, execle, execvp, execlp
fork() and execve() are system calls
fork-exec model:
fork() creates a copy of the current process
exec*() replaces the current process’ code and address
space with the code for a different program
• Whole family of exec calls – see exec(3) and execve(2)
// Example arguments: path="/usr/bin/ls",
// argv[0]="/usr/bin/ls", argv[1]="-ahl", argv[2]=NULL
void fork_exec(char *path, char *argv[]) {
pid_t pid = fork();
if (pid != 0) {
printf("Parent: created a child %d\n", pid);
} else {
printf("Child: about to exec a new program\n");
execv(path, argv);
}
printf("This line printed by parent only!\n");
}
Exec-ing a new program
Stack
Very high-level diagram of what
happens when you run the
Heap command “ls” in a Linux shell:
Data This is the loading part of CALL!
Code: /usr/bin/bash
fork()
parent child child
Stack
Stack Stack
exec*()
Heap Heap
Data Data Data
Code: /usr/bin/bash Code: /usr/bin/bash Code: /usr/bin/ls
This is extra
execve Example (non-testable)
material
Execute “/usr/bin/ls –l lab4” in child process using current
environment:
myargv[argc] = NULL
myargv[2] “lab4”
(argc == 3)
myargv[1] “-l”
myargv[0] “/usr/bin/ls”
myargv
envp[n] = NULL
envp[n-1] “PWD=/homes/iws/jhsia”
...
envp[0] “USER=jhsia”
environ
if (fork() == 0) {
printf("HC: hello from child\n");
exit(0);
} else {
printf("HP: hello from parent\n");
wait(&child_status);
printf("CT: child has terminated\n");
}
printf("Bye\n");
} forks.c
HC exit
printf Feasible output: Infeasible output:
HC HP
CT HP CT
HP Bye CT Bye
fork printf wait printf Bye HC
Example: Zombie
void fork7() {
if (fork() == 0) {
/* Child */
printf("Terminating Child, PID = %d\n",
getpid());
exit(0);
} else {
printf("Running Parent, PID = %d\n",
getpid());
linux> ./forks 7 & while (1); /* Infinite loop */
[1] 6639 }
Running Parent, PID = 6639 } forks.c
Terminating Child, PID = 6640
linux> ps
PID TTY TIME CMD
6585 ttyp9 00:00:00 tcsh
6639 ttyp9 00:00:03 forks
ps shows child process as
6640 ttyp9 00:00:00 forks <defunct> “defunct”
6641 ttyp9 00:00:00 ps
linux> kill 6639
[1] Terminated
Killing parent allows child to be
linux> ps reaped by init
PID TTY TIME CMD
6585 ttyp9 00:00:00 tcsh
6642 ttyp9 00:00:00 ps
Example:
void fork8() {
if (fork() == 0) {
/* Child */
Non-terminating printf("Running Child, PID = %d\n",
getpid());
Child
while (1); /* Infinite loop */
} else {
printf("Terminating Parent, PID = %d\n",
getpid());
exit(0);
}
} forks.c
linux> ./forks 8
Terminating Parent, PID = 6675
Running Child, PID = 6676 Child process still active even
linux> ps
PID TTY TIME CMD though parent has terminated
6585 ttyp9 00:00:00 tcsh
6676 ttyp9 00:00:06 forks
6677 ttyp9 00:00:00 ps Must kill explicitly, or else will
linux> kill 6676
linux> ps keep running indefinitely
PID TTY TIME CMD
6585 ttyp9 00:00:00 tcsh
6678 ttyp9 00:00:00 ps
Process Management Summary
fork makes two copies of the same process (parent & child)
Returns different values to the two processes
exec* replaces current process from file (new program)
Two-process program:
• First fork()
• if (pid == 0) { /* child code */ } else { /* parent code */ }
Two different programs:
• First fork()
• if (pid == 0) { execv(…) } else { /* parent code */ }
wait() example
waitpid() example
Example: Two consecutive forks
Bye