0% found this document useful (0 votes)
2 views

2.1.process

operating systems process

Uploaded by

Nagababu Katakam
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

2.1.process

operating systems process

Uploaded by

Nagababu Katakam
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 47

Operating Systems

Topic: Process

Endadul Hoque
Acknowledgement

• Youjip Won (Hanyang University)

• OSTEP book – by Remzi and Andrea Arpaci-Dusseau


(University of Wisconsin)
Revisit: An Operating System (OS)
• Responsible for
– Making it easy to run programs
– Allowing programs to share memory
– Enabling programs to interact with devices

OS is in charge of making sure the system


operates correctly and efficiently.

How does OS ensure this?


Revisit: Virtualization
• The OS takes a physical resource and transforms
it into a virtual form of itself.
– Physical resource: Processor, Memory, Disk …
• The virtual form is more general, powerful and
easy-to-use.
• Sometimes, we refer to the OS as a virtual
machine.
Revisit: Virtualizing the CPU
• The system has a very large number of virtual
CPUs.
– Turning a single CPU into a seemingly infinite number
of CPUs.
– Allowing many programs to seemingly run at once
→ Virtualizing the CPU
How to virtualize CPUs? – The crux

• Process or program execution means?


– Execution of program code →
execution of each instruction
code
static data
Program (exe file)

• Who executes any instruction?


– CPU
How to virtualize CPUs? – The crux

Process P
CPU
# code


eax
esp registers
PC
How to virtualize CPUs? – The crux

• Process P running on CPU

Process P
CPU
# code


eax
esp
PC
How to virtualize CPUs? – The crux

• Process P running on CPU

Process P
CPU
# code


eax
esp
PC
How to virtualize CPUs? – The crux

• Process P running on CPU


time
Process P
CPU
# code 𝑡0 𝑡𝑝



CPU is occupied by P
eax
esp
PC
How to virtualize CPUs? – The crux

• Process P and Q run on CPU


𝑡0 𝑡𝑝 𝑡𝑞

Process P
CPU time
# code Process Q

# code




eax …

esp
PC
Q after P – sequential,
but not interesting.
Why not concurrent?
But how?
How to virtualize CPUs? – The crux

• Process P and Q run on CPU concurrently


𝑡0 Δ𝑡

Process P
CPU time
# code
… Process Q

… # code

eax …

esp
PC
Time sharing
How to virtualize CPUs? – The crux

• Process P and Q run on CPU concurrently


𝑡0 Δ𝑡

Process P
CPU time
# code
… Process Q

… # code

eax …

esp
PC
Time sharing

What’s the underlying challenge?


How to virtualize CPUs? – The crux

• Process P and Q running concurrently – the challenge


𝑡0

Process P
CPU time
# code Δ𝑡
… Process Q
add %eax, 10
mov (%esp), %eax Because
# code %eax has
mov %eax, 2
wrong data…
eax …
So
… what to do?
esp
PC
Executing the
Sol: Save all intermediate dataExecuting
add instruction before theswitching
Timeto Q
sharing
and restore it beforemov
moving to P
instruction
Executing the
mov instruction
How to virtualize CPUs? – The crux

• Process P and Q running concurrently – solve the challenge


Because %eax holds
𝑡0 the
Process P correct value
CPU time
# code Δ𝑡
… Process Q
add %eax, 10
mov (%esp), %eax # code
mov %eax, 2
eax …

esp
PC
Executing the
Register
add instruction Executing the Context
mov instruction of Q
Executing the
Register Context of P
mov instruction
How to provide the illusion of many CPUs?

• CPU virtualizing
– The OS can promote the illusion that many virtual
CPUs exist.
– Time sharing: Running one process, then stopping it
and running another
• The potential cost is performance.
Space sharing:
the counterpart
How to implement (e.g., disk space)
virtualization of the CPU?
OS needs
• Some low-level machinery (mechanisms)
• Some high-level intelligence (policies)
Policy vs. Mechanism
• In many OSes, a common design paradigm
– Separate high-level policies from low-level
mechanisms
• Policy: provides answer to which/what question
– E.g., which process should the OS run now?
– E.g., only Alice should read file f
• Mechanism: provides answer to how question
– E.g., how does OS perform a context switch?
– E.g., encrypt file f
• A general software design principle: modularity
A Process
A process is a running program

• Comprising of a process (aka machine state)


– Memory (address space)
• Instructions
• Data section
– Registers
• Program Counter (PC) Analogy based on Java
or Instruction Pointer (IP)
• Stack pointer w/ frame pointer Class ↦ Object
– I/O information Program ↦ Process
• E.g., open files
Process API
• These APIs are available on any modern OS.
– Create
• Create a new process to run a program
– Destroy
• Halt a runaway process
– Wait
• Wait for a process to stop running
– Miscellaneous Control
• Some kind of method to suspend a process and then resume it
– Status
• Get some status info about a process
Process Creation
CPU Memory
code
static data
heap

stack
Process

Loading:
code Takes on-disk program
static data and reads it into the
address space of process
Program
Disk
Process Creation
1. Load a program code into memory, into the
address space of the process.
– Programs initially reside on disk in executable format.
– OS perform the loading process lazily.
• Loading pieces of code or data only as they are needed
during program execution.

2. The program’s run-time stack is allocated.


– Use the stack for local variables, function parameters,
and return address.
– Initialize the stack with arguments → argc and the
argv array of main() function
Process Creation
3. The program’s heap is created.
– Used for explicitly requested dynamically allocated data.
– Use malloc() for requesting space and free()to release it

4. The OS does some other initialization tasks.


– input/output (I/O) setup
– Each process by default has three open file descriptors:
Standard input (stdin), output (stdout) and error (stderr)

5. Start the program running at the entry point, namely


main().
– The OS transfers control of the CPU to the newly-created process.
Process States
• A process can be one of three states.
– Running
• A process is running on a processor.
– Ready
• A process is ready to run but for some reason the OS has
chosen not to run it at this given moment.
– Blocked
• A process has performed some kind of operation.
• When a process initiates an I/O request to a disk, it becomes
blocked and thus some other process can use the processor.
Process State Transition

Descheduled
Running Ready
Scheduled

I/O: initiate I/O: done

Blocked
Tracing Process State
Tracing Process State
Data Structures
• The OS has some key data structures that track
various relevant pieces of information.
– Process list
• Ready processes
• Blocked processes
• Current running process
– Register context

• PCB(Process Control Block)


– A C-structure that contains information
about each process.
Example: The xv6 kernel Proc Structure
// the registers xv6 will save and restore
// to stop and subsequently restart a process
struct context {
int eip; // Index pointer register
int esp; // Stack pointer register
int ebx; // Called the base register
int ecx; // Called the counter register
int edx; // Called the data register
int esi; // Source index register
int edi; // Destination index register
int ebp; // Stack base pointer register
};

// the different states a process can be in


enum proc_state { UNUSED, EMBRYO, SLEEPING,
RUNNABLE, RUNNING, ZOMBIE };
Example: The xv6 kernel Proc Structure
// the registers xv6 will save and restore
// the information xv6 tracks about each process
// //
toincluding
stop anditssubsequently restart
register context and a process
state
struct
structcontext
proc { {
int eip;
char *mem; // Index//pointer
Start ofregister
process memory
int esp;
uint sz; // Stack//pointer
Size ofregister
process memory
int ebx;
char *kstack; // Called// the base
Bottom of register
kernel stack
int ecx; // Called// the
for counter
this process
register
enum
int proc_state
edx; //state;
Called//the
Process
datastate
register
intesi;
int pid; // Source// index
Process ID
register
struct proc *parent; // Parent process
int edi; // Destination index register
void *chan; // If non-zero, sleeping on chan
int ebp;
int killed; // Stack base
// pointer register
If non-zero, have been killed
}; struct file *ofile[NOFILE]; // Open files
struct inode *cwd; // Current directory
// thestruct
different states
context a process
context; // Switchcan be to
here in run process
enum proc_state { UNUSED,
struct trapframe *tf; EMBRYO, SLEEPING,
// Trap frame for the
RUNNABLE,// RUNNING,
current interrupt
ZOMBIE };
};
UNIX/LINUX PROCESS API
Read The Man Pages
• Manual (Man) pages are the original form of
documentation that exist on UNIX systems

• Spend some time reading man pages


– A key step in becoming a systems programmer
– There are tons of useful tidbits hidden there

• Reading them can save you some


embarrassment (in professional settings) and
debugging time
fork()
• Create a new process
– The newly-created process has its own copy of the address space,
registers, and PC.
#include <stdio.h>
#include <stdlib.h> p1.c
#include <unistd.h>
int main(int argc, char *argv[]){
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0) { // fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
} else if (rc == 0) { // child (new process)
printf("hello, I am child (pid:%d)\n", (int) getpid());
} else { // parent goes down this path (main)
printf("hello, I am parent of %d (pid:%d)\n",
rc, (int) getpid());
}
return 0;
}
fork()
Result (Not deterministic)
prompt> ./p1
hello world (pid:29146)
hello, I am parent of 29147 (pid:29146)
hello, I am child (pid:29147)
prompt>

OR
prompt> ./p1
hello world (pid:29146)
hello, I am child (pid:29147)
hello, I am parent of 29147 (pid:29146)
prompt>
wait()
• This system call won’t return until the child has run and exited
#include <stdio.h>
#include <stdlib.h> p2.c
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char *argv[]){
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0) { // fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
} else if (rc == 0) { // child (new process)
printf("hello, I am child (pid:%d)\n", (int) getpid());
} else { // parent goes down this path (main)
int wc = wait(NULL);
printf("hello, I am parent of %d (wc:%d) (pid:%d)\n",
rc, wc, (int) getpid());
}
return 0;
}
wait()
Result (Deterministic)
prompt> ./p2
hello world (pid:29266)
hello, I am child (pid:29267)
hello, I am parent of 29267 (wc:29267) (pid:29266)
prompt>
More on wait()
• wait() vs waitpid()
• When to use waitpid()?
• Some cases where wait() returns before the
child exits
– What is a process group? How is this related to
wait()?
• Relationship between wait() and child processes
running in background?

Read the man pages


exec()
• Run a program that is different from the calling program
#include <stdio.h> p3.c
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>

int main(int argc, char *argv[]){


printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0) { // fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
} else if (rc == 0) { // child (new process)
printf("hello, I am child (pid:%d)\n", (int) getpid());
char *myargs[3];
myargs[0] = strdup("wc"); // program: "wc" (word count)
myargs[1] = strdup("p3.c"); // argument: file to count
myargs[2] = NULL; // marks end of array

exec()
• Run a program that is different from the calling program
#include <stdio.h> p3.c
#include <stdlib.h>
#include <unistd.h>

#include <string.h>
execvp(myargs[0],
#include <sys/wait.h> myargs); // runs word count
printf("this shouldn’t print out");
} else
int { argc,
main(int // parent goes down this path (main)
char *argv[]){
int wc = wait(NULL);
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
printf("hello, I am parent of %d (wc:%d) (pid:%d)\n",
if (rc rc,
< 0) wc,
{ // fork failed; exit
(int) getpid());
} fprintf(stderr, "fork failed\n");
exit(1);
return 0;
} else if (rc == 0) { // child (new process)
} printf("hello, I am child (pid:%d)\n", (int) getpid());
char *myargs[3];
myargs[0] = strdup("wc"); // program: "wc" (word count)
myargs[1] = strdup("p3.c"); // argument: file to count
myargs[2] = NULL; // marks end of array

exec()
printf("hello, I am child (pid:%d)\n", (int) getpid());
... ...
execvp(myargs[0], myargs); // runs word count
printf("this shouldn’t print out");
} else { // parent goes down this path (main)
int wc = wait(NULL);
printf("hello, I am parent of %d (wc:%d) (pid:%d)\n",
rc, wc, (int) getpid());
}
return 0; Excerpt from p3.c
}

Result
prompt> ./p3
hello world (pid:29383)
hello, I am child (pid:29384)
29 107 1030 p3.c
hello, I am parent of 29384 (wc:29384) (pid:29383)
prompt>
exec() family
• On Linux, there are six variants of exec()
– execl(), execlp(), execle(),
execv(), execvp(), execvpe()

Read the man pages

A pictorial presentation:
https://gist.github.com/fffaraz/8a250f896a2297db06c4
I/O Redirection
p4.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/wait.h>

int
main(int argc, char *argv[]){
int rc = fork();
if (rc < 0) { // fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
} else if (rc == 0) { // child: redirect standard output to
a file
close(STDOUT_FILENO);
open("./p4.output", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);

I/O Redirection
p4.c
#include <stdio.h>

#include <stdlib.h>
// now exec "wc"...
#include <unistd.h>
char *myargs[3];
#include <string.h>
myargs[0] = strdup("wc"); // program: "wc" (word count)
#include <fcntl.h>
myargs[1] = strdup("p4.c"); // argument: file to count
#include <sys/wait.h>
myargs[2] = NULL; // marks end of array
execvp(myargs[0], myargs); // runs word count
int
} else { // parent goes down this path (main)
main(int argc, char *argv[]){
int wc = wait(NULL);
int rc = fork();
}
if (rc < 0) { // fork failed; exit
return 0;
fprintf(stderr, "fork failed\n");
}
exit(1);
} else if (rc == 0) { // child: redirect standard output to
a file
close(STDOUT_FILENO);
open("./p4.output", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);

I/O Redirection
p4.c
#include <stdio.h>

#include <stdlib.h>
// now exec "wc"...
prompt>
#include ./p4
<unistd.h>
char *myargs[3];
#include <string.h>
prompt> cat
myargs[0] p4.output// program: "wc" (word count)
= strdup("wc");
#include <fcntl.h>
Result
myargs[1] = strdup("p4.c"); // argument: file to count
32 109
#include 846= p4.c
<sys/wait.h>
myargs[2] NULL; // marks end of array
int prompt>
execvp(myargs[0], myargs); // runs word count
} else { // parent goes down this path (main)
main(int argc, char *argv[]){
int wc = wait(NULL);
int rc = fork();
}
if (rc < 0) { // fork failed; exit
return 0;
fprintf(stderr, "fork failed\n");
}
exit(1);
} else if (rc == 0) { // child: redirect standard output to
a file
close(STDOUT_FILENO);
open("./p4.output", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);

Other Process API
• pipe()
– E.g., grep -o foo file | wc -l
– the output of one process (i.e., grep) is connected to an in-
kernel pipe (i.e., queue), and the input of another process (i.e.,
wc) is connected to that same pipe
• kill()
– send signals to a process (e.g., pause, die, terminate and so on)
– Control-c sends a SIGINT (interrupt) to the process to normally
terminate it
– Control-z sends a SIGTSTP (stop) to the process to pause it

Can a user send signals (e.g., SIGINT)


to any arbitrary process?
Read the man pages
Some Useful Shell Commands
• ps
– Display which processes are running
• top
– Display the processes of the system, the resources and
their status
• kill/killall
– Send different signals to processes

Read the man pages


Reading Material

• Chapter 4, 5 of OSTEP book – by Remzi and Andrea


Arpaci-Dusseau (University of Wisconsin)
http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-intro.pdf
http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-api.pdf
Questions?

You might also like