cp386 Notes
cp386 Notes
Chapter 3 : Processes
Before we only had one program to be executed at a time.
Process is the program under execution. It had been loaded into RAM. For execution for a
program (a process) needs resources.
Process can be called as a job or a task. A process has multiple things, for example, text
section (set of instructions), program counter, stack for temporary data, data section for global
variable, heap for dynamically allocated memory.
There are also different sections for data. Stack, heap, initialized data, initialized data.
Process state:
New: the process is being created
Running: instructions are being executed (running on CPU)
Waiting: the process is waiting for some event to occur (waiting for I/O request)
Ready: The process is waiting to be assigned to a processor
Terminated: The process has finished execution
Process control Block (PCB):
Information associated with each process. PCB is going to be created while running the
process for that particular process.
-Process state
-Program counter
-CPU registers
-CPU scheduling
-CPU scheduling information
-…
PCB is a double linked list.
Thread:
Thread is a thing that keeps different functions to be executed in different thread so it can be
handled in an easier way.
We want to maximize the CPU use since we are average using only 10% of CPU. Every clock
can only execute one hardware function. Degree of multiprogramming is important, it means
the number of processes currently in memory.
I/O bound process(spend more time doing on I/O handling) use less cpu cycle and CPU
bound process(do more computataions) use more cpu cycle.
Process scheduling:
Short-term scheduler (cpu scheduler): select the process in ram and allocate it on cpu
Long-term scheduler: select process that should be brought to ready queue.
Medium-term scheduler: Not now
Context switch:
Context is what is inside the PCB. When a process is running, it updates PCB. When a
process is executing and it is on the waiting stage or there is an interrupt, it will store the
process into its PCB and save its state, and it will reload another PCB for another process, so
it is doing work. And when the previous process is going to be loaded again, it will load the
PCB of the previous process and execute from the place where it was paused.
A system should do a program creation and process termination. Each process can create
children processes and each process has a pid.
Resource sharing options: parent and children share all resources, children share subset of
parent’s resources, parent and child share no resources
Memory is the first resources that parent and children should share.
fork() is the system call for creating a new process
The child is a copy of the parent but it has a different pid and its resource utilization is set to
0. fork() returns child’s pid to the parent and 0 to the child.
exec() command is also important. This command is used when we want to let child process
to execute something different than parent process
There are different kinds of exec() command.
execl(const char path, const char arg, … NULL)
execlp(const char path, const char arg, … NULL) it does not need the path to built in binary
file
execv() we can pass the argument like the command line and the last value od the argument
should be null
execvp(const char file, char const argv) pass a file to execute
we can use wait(NULL) in parent part of the code to let it execute after all the child’s process
is executed.
exit() function call is called by default when the process is terminated. You can also manually
call it to terminate a process.
Use exit(0) when you want to finish it clean and use exit(1) to send an error to the parent
process.
Linux has 3 standard file descriptors:
Stdin: standard input file descriptor. To take inout from the terminal by default.
Stdout: standard output file descriptor. Used to print something to the console.
Stderr: standard error file descriptor.
dup() system call: This is a system call that will create the copy of the file descriptor.
dup2() takes two arguments and assign the file descriptor of first argument to second
argument.
Wait() system call make sure that child process to finish first and then go to parent process.
Cascading termination means some process that does not allow child process to exist after the
parent process is totally exited.
Zombie process happens when parent process did not call wait
Orphan process is parent process terminated without invoking wait.
Independent process means processes that cannot affect and be affected by other process and
cooperating process is opposite.
Cooperating needs interprocess communication (IPC) Two models of IPC is shared memory
and message passing.
Interprocess communication:
a) Message passing
b) Shared memory
Shared memory:
unbounded buffer: place no practical limit on buffer
bounded buffer assumes that there is a fixed size for buffer
When producer process is creating data, the consumer data will absorb data from the buffer
and this is called bounded buffer shared memory solution.
If the buffer is full, it does nothing ((in + 1) % BUFFER_SIZE == out)
Two variables (in and out) checks processes and in tells producer process to see where it is
going to insert data using in and updates it, and out variable checks to see where consumer
process is going to take data and updates it.
Shm_open(), mmap(), munmap(), sprintf(), display(), shm_close(), shm_unlink()
Message passing:
using send() and receive() to send message for interprocessing
If there are two processes, we need to establish a communication link and then exchange
messages by system call
Interprocessing needs to know where they are sending the message. They knows each other
by process ID (PID)
Direct and indirect communication
Synchronization:
Blocking and non-blocking send and receive
Pipes:
Sending the output of one command to next command as the input.
Ex: ls | … (| is a pipe symbol, whatever ls output will be send to …)
Ordinary pipes: Producer writes to one end and consumer reads from the other end. This is
unidirectional which means this can only send in one way. If we want to send bidirectional,
we need to create two pipes.
Creating a pipe:
Create an array of size 2 and we pass this array to pipe() system call. Pipe() system call create
a pipe for communication.
Int p[2]; pipe(p) => creates a pipe called p
This creates read_end = 0 and write_end = 1
In parent process, it will close read_end (close(p[0])) and write on the write_end. After the
writing process it needs to close the pipe.
In child process, it close the write_end first and read from the read_end. After the process, it
will close the read_end too.
Both processes can use read and write end to send data to the other process.
Socket:
Combination of ip address and port number
RPC (remote procedure calls): initiates by my device which has a match maker code. Match
maker code tries to read the socket and tries to make the request to the other socket. (Client to
server) and then it is normal request and sending message from server to client.
Chapter 4:
Threads and concurrency
Theas is light-weight and efficient and modern kernels are generally multithreaded
Each Thread also has a thread ID
Things are shared between threads are code, data and files and each thread has each own
registers and stack
Difference between threads and processes is thread is light-weighted, easy to create and
terminate and it only runs within the process.
Threads do not depend on any OS system calls.
Example of multi-thread applications: If the web server ran as a traditional single threaded
process, it would be able to service only one client at a time, and a client might have to wait a
very long time for its request to be serviced.
In multi-threading, when a client request, server create a new thread to service the request and
the server resume listening for additional client requests.
Benefits: Responsiveness, resource sharing, economy, scalability
Mulitcore or Multiprocessor architecture have certain problems:
Dividing activities. Balance, data splitting, data dependency, testing and debugging
Parallelism implies a system can perform more than one task simultaneously
Concurrency supports more than one task making progress
Amdahl’s law: used to calculate the speed of code execution by adding more code.
Kernel thread is the one that is going to run on cpu.
MANY-TO-ONE
Many user-level threads mapped to single kernel thread.
Multiple threads may not run in parallel on multicore since only one kernel thread is running
ONE-TO-ONE
There are the same number of kernel thread will be created when the user creates a thread.
The progress of the thread will be faster
MANY-TO-MANY
Allows many user level threads to be mapped to many kernel threads. The number of kernel
thread depends on your hardware.
pthread.h library needs to be included to make multithread program works.
pthread_create(pthread_t *thread, const pthread_attr_t *attr,) is used to create a thread
pthread_join() join with a terminated thread
pthread_self() returns the thread ID of itself
pthread_equal() comparing the thread
pthread_exit() exiting a thread
Chapter 5:
CPU burst: load store, add store, read from file
A CPU burst is followed by an I/O burst
CPU burst and I/O burst should be followed by one another and CPU burst is the one that is
starting the process.
Mostly, CPU burst duration is mostly from 4 to 5 milliseconds.
Compile Intensive: matrix multiplication
I/O Intensive: Data transfer
There are some process or jobs that have more of compile intensive task or I/O intensive task.
All the processes are kept in RAM and the number of processes that it can takes is called
degree of multiprogramming
Two types of scheduler:
Short-term scheduler: allocates program to CPU. CPU scheduling decisions may take place
when a process switches from running to waiting state, switching from running to ready state,
switches from waiting to ready, terminates. Scheduling under these processes is
nonpreemptive (cooperative)
Context switching: Changing from one of the process to another process. (P0 executing ->
save state into PCB0 -> restore from PCB1 -> P1 executing) This job is done by dispatcher.
We need to create an algorithm to allocate process to CPU and there are some criteria to
compare different algorithm:
CPU utilization: Keep the CPU as busy as possible. (max)
Throughput: number of processes that complete their execution per time unit (max)
Turnaround time: amount of time to execute a particular process (min)
Waiting time: amount of time a process has been waiting in the ready queue. (min)
Response time: amount of time it takes from when a request was submitted until the first
response is produces. (min)
First come, first served scheduling: using a queue to schedule different processes.
This algorithm is non-preemptive.
Convoy effect: This effect is short process behind long process
CPU-bound processes means processes that takes longer time to execute and keep other
processes to be waited.
I/O-bound processes usually take lesser time.
Shortest-job-first scheduling: (SJF)
Execute the shortest processes first.
Determining length of next CPU burst
Thread are also scheduled. To run on a CPU, user threads must ultimately be mapped to an
associated kernel thread to run on CPU
Each process can have their own thread and the number of kernel thread are the total number
of LWP.
Total number of LWP = number of LWP for SCS + number of LWP for PCS
Number of LWP for SCS = Number of SCS threads
Number of LWP for PCS = Depends on application developer
If thread is defined as process-contention scope, many threads can compete for one LWP
If the thread is defined as system-contention scope, one thread is allocated to one LWP
Real-time CPU scheduling
Soft real-time systems:
No guarantee as to when critical real-time process will be scheduled
Hard real-time systems
Task must be serviced by its deadline
Chapter 6:
Race condition: when programs update the same value and try to modify the same value at
the same time, it will give an error
Critical section: area of the program where to update of a common variable is dangerous
Solution to critical section:
Mutual exclusion: if process P is executing, no other processes can be executing in their
critical section
Progress: If no process is executing, then it should be allow to enter the critical section
Bounded waiting: A bound must exist on the number of times that other processes are allowed
to enter their critical sections after a process has made a request to enter its critical section and
before that request is granted.
Turn integer decides which process is entering critical section and flags[2] indicate if a
process is read to enter the critical section or not.
This is called a peterson’s solution and this may not work because modern computer
architecture swaps the execution time of setting flag and turn. This only works if there are
only two processes.
Atomic = non-interruptible
Some computer provide atomic instruction to let a process run and not being interrupted
Test_and_set(&lock) to see if another process is in critical section and to see if it is locked or
not
Compare_and_Swap(int *value, int expected, int new_value) is another algorithm to check
the critical section is used by other processes or not.
Mutex locks:
Mutex locks are os designers that helped developer to manage critical sections
Uses acquire() and release() to lockdown the critical section
Do{
Acquire lock
Critical section
Release lock
Remainder section
}
Semaphore:
Synchronization tool that provides more sophisticated way for process to synchronize their
activities
Wait() and signal() is used to manage critical section
Chapter 8:
Deadlock: When the processes are all waiting for the resource allocation and waiting until it
get free. They are trying to access the resources that are already acquired
It is most likely that there will be a deadlock when there is a cycle in the graph but there may
be situations that deadlock will be broken by one of the process that finish itself and release
the resource that is required by other process.
We have sequence of processes because there are limited resources. A process request, use
and release resources. They do it by different system calls. All of the processes that require a
resource can be put to the waiting queue for the resources
Deadlock makes the process to not process more since it is in a deadlock
Foe handling deadlock, we use a system call called pthread_mutex_trylock(). This keep a
spinning operation until the resources that it requires are available.
4 conditions for deadlock to occur:
1. Mutex exclusion: only one process at a time can use a resources
2. Hold and wait: a process holding at least one resources is waiting to acquire
additional resources held by other resources
3. No preemption: a resources can be released only voluntarily by the process holding it,
after that process has completed its task
4. Circular wait: There exists a set of waiting processes such that p0 is waiting for a
resource that is held by p1, p1 is waiting for resource held by p2 and so on and so
forth
Approach to prevent deadlock:
Mutual Exclusion – not required for sharable resources
Hold and Wait – must guarantee that whenever a process requests a resource, it does not hold
any other resources. Starvation may occur and low resource utilization
If a process that is holding some resources requests another resource that cannot be
immediately allocated to it, then all resources currently being held are released
If a process is holding resources with lower number, only then it can request for more
resources
Deadlock avoidance:
It will not let a system to goes into a deadlock situation. Whenever a process goes into a
system, it announces the resources that it is required and it preforms some calculation.
Safe state: A sequence of order of thread that can complete execution with limited execution.
If the threads does not have a safe state, it may cause a deadlock
Avoidance of deadlock keeps the system in safe state.
We always want our system in a safe state. Calculation is required to see if the request of a
thread will go into an unsafe state or not.
There can be a claim edge in the resource allocation graph if a thread requires a resource in
the future
Claim edge can detect if the request of a thread and the allocation of the resources will create
a cycle and eventually a deadlock or not.
Banker’s algorithm: When a user requests a set of resources, the system must determine
whether the allocation of these resources will leave the system in a safe state
Data structure of banker’s algorithm:
N = number of processes, m = number of resources type
Available: vector of length m, if available [j] = k, there are k instances of resource type R j
available
Max: n * m metrix. If max[i][j] = k, then process Tj may request at most k instances of
resource type Rj
Allocation: n * m matrix. If allocation[i][j] = k, then Tj is currently allocated k instances of Rj
Need: n * m matrix. I f need[i][j] = km then Tj may need k more instances of Rj to complete
its task.
Need[i][j] = Max[i][j] – allocation[i][j]
Max and allocation matrix will be given
We use these metrices to see if there is a sequence of thread
Safety algorithm is also executed to find a certain order by which it should be executing
different threads. If it does not find the sequence, it means the system may create a deadlock.
1. Let Work and Finish be vectors of length m and n. Initialize Work = Available and
Finish[i] = false for I = 0 to n – 1
2. Find an index I such that Finish[i] == false && Needi <= Need
3. Work = Work + Allocationi, Finish[i] = true and go back to step 2
4. If Finish[i] == true for all I, then the system is in a safe state
This is a compute heavy operation since it may take m + n 2 time to operate
Resource request algo for Pi:
1. If Request <= Need go to step 2. Otherwise, raise error condition, since process has
exceeded its maximum claim
2. If Requesti <= Available, go to step 3. Otherwise Ti must wait, since resources are not
available.
3. Pretend to allocate requested resources to Ti by modifying the state as follow:
Available = Available – Request
Allocation = Allocation + Request
Need = Need – Request
If these states are safe, we can allocate the resources to them
Deadlock Detection:
If there is a deadlock, there is an algorithm to check if there is deadlock or not.
Chapter 8:
System model of deadlock: Request, use and release resources.
Deadlock characterization: What happens in deadlock is the resources that are used in other
processes and the resources could not distributed to other process. There is no pre-emption in
allocating resources.
Livelock: a livelock can happen when a thread keeps trying a failing action over and over.
-Mutual exclusion
-hold and wait
-no pre-emption
-circular wait
Scenario will be given to see if there is a cycle and will go into a deadlock or not.
Methods of handling deadlock: Safety algo: using the banker’s algo to see if the processes
will be inside a deadlock or not
Deadlock prevention: Mutual exclusion to prevent. True or False question
We use safety algo to see if a particular process will be granted or not
Deadlock Avoidance: Single instance use a resource-allocation graph
Multiple instances use the banker’s algo
Deadlock detection: We detect if there is a deadlock to see if there is a cycle or not. Very
similar algo to banker’s algo but there is a small difference. Tries to find out where if any
finish[i] == false. Run through every process to see if we can find a safe sequence or not.
Everything is the same but the finish array
Allow process to enter deadlock and we will recover from it
Recovery from deadlock: minimize the cost and rollback to a safe state. Needs to prevent
starvation
Chapter 9: About memory
We need to know that a program is something in the secondary storage, when we need to
execute it, we bring it to main memory and put it in CPU. When the process is loaded it is
converted into pages. Position 0 will be in page 0 and due to partition, the code will be
separated into different pages. It must be taken from the main memory and this is what we are
going to discuss. RAM is storing OS too and we are going to convert logical address to
physical address done by MMU (memory management unit)
What is base and limit register: use to protect processes from entering into different processes.
Address binding: compile time, load time and execution time binding (know all of this)
Logical and physical memory: logical address is generated by CPU and physical address is
used by RAM
First-fit, best-fit and worst-fit: first fit hole, smallest fit hole and largest fit hole
External fragmentation and internal fragmentation: contiguous allocation causes external
fragmentation which a process does not take up all the block and there are some spaces
wasted. Solution to this problem is to move all the processes to one side and all the blank
spaces to the other side so the blank space can allocate a new process.
50-percent rule: 0.5N / (0.5N + N) = 1/3
Internal fragmentation is memory allocated to a process is slightly larger than the requested
memory.
Remember 210 is 1024 Bytes and it is 1 KB
When the pages are assigned, it is always the power of 2.
10 address lines are used to allocate 1KB of memory.
Address translation is used by a page number and page offset. M (logical address) is given
and the offset is d, how many lines are for page table.
Logical address is 10 bit and out of 10 bits, 4 bits are offset. Then 6 bits will be the page
number. 6 bits will be used to index a page table. The size of the table will be 2 6 since there
will be 6 address lines.
Expect question on paging. Slide 47
Effective access time and hit ratio (slide 57): 100ns for memory access and hit ratio of 80%
EAT = 0.8 * 100 + 0.2 * 200 = 120ns. Effective access time will be 120ns
Shared pages: pages that are shared in different program
Two level paging: We need to identify two level or three level paging scheme.
Swapping: Theoretical question on swapping
Chapter 10: Virtual memory
Step in handling a page fault. Knows about the concept for page fault (order of instructions)
Pure demand paging: expect question on pure demand paging
Page replacement algorithm, reference string given and find the number of page fault on FIFO
algo, optimal algo (look at the future), least recently used algo (look at the past) Stack algo
will also be asked
Approximation algo is also important and may see a question on fixed allocation.
Global and local replacement for conceptual question
Chapter 14: File system
File system in general and what is file system
FCB is important and file system structure is important
Allocation methods- contiguous: direct access and fetch immediately
Linked allocation: no direct access and cannot find back once it is lost
Free space management in the video and it is important