Jump into concepts and practice - no test required
or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
▶
Steps
setup
Initialize variables and start scheduling
Initialize remaining times, counters, and time to start scheduling from time 0.
💡 Setting up these variables is essential to track progress and remaining burst times for each process.
Line:n = len(processes)
remaining_time = [bt for _, bt in processes]
complete = 0
current_time = 0
💡 We now have the initial state with all processes' burst times ready to be decremented as they run.
compare
Select shortest process at time 0
Check all processes that have arrived by current_time=0 and select the one with the shortest remaining time.
💡 At time 0, only process 0 has arrived, so it must be selected to run.
Line:for i in range(n):
if (processes[i][0] <= current_time and remaining_time[i] < min_remaining and remaining_time[i] > 0):
min_remaining = remaining_time[i]
shortest = i
check = True
💡 The algorithm picks the shortest job among arrived processes, here only P0.
traverse
Run process 0 for 1 time unit
Decrement remaining time of process 0 by 1 and advance current_time to 1.
💡 Running the selected process reduces its remaining burst time and moves time forward.
💡 The CPU executes the process for one unit, simulating time passing.
compare
At time 1, select shortest process again
At current_time=1, processes 0 and 1 have arrived. Select the one with the shortest remaining time.
💡 The algorithm checks all arrived processes to decide if preemption is needed.
Line:for i in range(n):
if (processes[i][0] <= current_time and remaining_time[i] < min_remaining and remaining_time[i] > 0):
min_remaining = remaining_time[i]
shortest = i
check = True
💡 Preemption occurs because a shorter job (P1) has arrived.
traverse
Run process 1 for 1 time unit
Decrement remaining time of process 1 by 1 and advance current_time to 2.
💡 Executing the newly selected shortest job reduces its burst time.
💡 The CPU switches to the shorter job and executes it.
compare
At time 2, select shortest process again
At current_time=2, processes 0,1,2 have arrived. Select the shortest remaining time process.
💡 The algorithm continuously checks for the shortest remaining job to run.
Line:for i in range(n):
if (processes[i][0] <= current_time and remaining_time[i] < min_remaining and remaining_time[i] > 0):
min_remaining = remaining_time[i]
shortest = i
check = True
💡 No preemption needed since current running process is still shortest.
traverse
Run process 1 for 1 time unit
Decrement remaining time of process 1 by 1 and advance current_time to 3.
💡 Process 1 continues execution, reducing its remaining burst time.
💡 The CPU continues executing the shortest job without interruption.
compare
At time 3, select shortest process again
At current_time=3, all processes have arrived. Select the shortest remaining time process.
💡 The algorithm checks all arrived processes to find the shortest remaining job.
Line:for i in range(n):
if (processes[i][0] <= current_time and remaining_time[i] < min_remaining and remaining_time[i] > 0):
min_remaining = remaining_time[i]
shortest = i
check = True
💡 The running process is still the shortest, so no preemption occurs.
traverse
Run process 1 for 1 time unit
Decrement remaining time of process 1 by 1 and advance current_time to 4.
💡 Process 1 continues execution, moving closer to completion.
💡 The algorithm tracks completion and waiting time precisely at process finish.
compare
At time 5, select shortest process again
At current_time=5, select the shortest remaining time process among P0, P2, and P3.
💡 The algorithm picks the next shortest job to run after a process finishes.
Line:for i in range(n):
if (processes[i][0] <= current_time and remaining_time[i] < min_remaining and remaining_time[i] > 0):
min_remaining = remaining_time[i]
shortest = i
check = True
💡 The algorithm continues selecting the shortest job dynamically.
traverse
Run process 3 for 1 time unit
Decrement remaining time of process 3 by 1 and advance current_time to 6.
💡 Executing the selected process reduces its remaining burst time.
💡 The CPU executes the process for one unit, simulating time passing.
compare
At time 6, select shortest process again
At current_time=6, select the shortest remaining time process among P0, P2, and P3.
💡 The algorithm checks all arrived processes to find the shortest remaining job.
Line:for i in range(n):
if (processes[i][0] <= current_time and remaining_time[i] < min_remaining and remaining_time[i] > 0):
min_remaining = remaining_time[i]
shortest = i
check = True
💡 The running process is still the shortest, so no preemption occurs.
traverse
Run process 3 for 1 time unit
Decrement remaining time of process 3 by 1 and advance current_time to 7.
💡 Process 3 continues execution, reducing its remaining burst time.
💡 The CPU continues executing the shortest job without interruption.
compare
At time 7, select shortest process again
At current_time=7, select the shortest remaining time process among P0, P2, and P3.
💡 The algorithm checks all arrived processes to find the shortest remaining job.
Line:for i in range(n):
if (processes[i][0] <= current_time and remaining_time[i] < min_remaining and remaining_time[i] > 0):
min_remaining = remaining_time[i]
shortest = i
check = True
💡 The running process is still the shortest, so no preemption occurs.
traverse
Run process 3 for 1 time unit
Decrement remaining time of process 3 by 1 and advance current_time to 8.
💡 Process 3 continues execution, reducing its remaining burst time.
💡 The algorithm tracks completion and waiting time at process finish.
compare
At time 10, select shortest process again
At current_time=10, select the shortest remaining time process among P0 and P2.
💡 The algorithm picks the next shortest job to run after a process finishes.
Line:for i in range(n):
if (processes[i][0] <= current_time and remaining_time[i] < min_remaining and remaining_time[i] > 0):
min_remaining = remaining_time[i]
shortest = i
check = True
💡 The algorithm continues selecting the shortest job dynamically.
traverse
Run process 0 until completion
Process 0 runs for remaining 7 time units, completes at time 17, waiting time calculated.
💡 Completing a process updates counters and waiting time precisely.
Transitionrunning → terminated0 - process completed
0
terminated
burst: 0
1
terminated
burst: 0
2
ready
burst: 9
3
terminated
burst: 0
Ready Queue
2
Waiting Queue
empty
🖥CPU0t=17
idle
1
3
idle
Transitionrunning → terminated pid:2 - process completed
0
terminated
burst: 0
1
terminated
burst: 0
2
terminated
burst: 0
3
terminated
burst: 0
Ready Queue
empty
Waiting Queue
empty
🖥CPU2t=26
idle
1
3
idle
2
Key Takeaways
✓ SJF preemptive scheduling always picks the process with the shortest remaining burst time at every time unit.
This dynamic selection is difficult to visualize from code alone but is clear when watching each scheduling decision.
✓ Preemption occurs immediately when a shorter job arrives, interrupting the currently running process.
Seeing the CPU switch processes step-by-step reveals how preemption minimizes waiting time.
✓ Waiting time is calculated precisely at process completion using finish time, burst time, and arrival time.
Understanding waiting time calculation is easier when you see the exact moment a process finishes and how the formula applies.
Practice
(1/5)
1. In which of the following scenarios is the concept of 'Hold and Wait' most likely to cause a deadlock?
easy
A. A process can forcibly preempt resources from other processes.
B. A process requests all required resources at once before execution begins.
C. A process releases all resources before requesting new ones.
D. A process holds one resource and waits to acquire another resource already held by another process.
Solution
Step 1: Understand 'Hold and Wait'
This condition requires a process to hold at least one resource while waiting to acquire additional resources. A process holds one resource and waits to acquire another resource already held by another process directly describes this scenario.
Step 2: Analyze other options
A process requests all required resources at once before execution begins avoids hold and wait by requesting all resources upfront. A process releases all resources before requesting new ones releases resources before requesting new ones, preventing hold and wait. A process can forcibly preempt resources from other processes describes preemption, which is a different condition.
Final Answer:
Option D -> Option D
Quick Check:
Only a process holding one resource and waiting to acquire another resource already held by another process matches the hold and wait condition necessary for deadlock.
Hint: Hold and Wait means holding some resources while waiting for others [OK]
Common Mistakes:
Confusing hold and wait with requesting all resources at once
Thinking preemption is part of hold and wait
2. In which scenario is First-Come, First-Served (FCFS) scheduling most appropriate to use?
easy
A. When all processes have similar CPU burst times and arrival times
B. When minimizing average waiting time is the highest priority
C. When process arrival times are unpredictable and preemption is required
D. When simplicity and fairness in process order are more important than responsiveness
Solution
Step 1: Understand FCFS characteristics
FCFS schedules processes in the order they arrive without preemption, making it simple and fair in terms of arrival order.
Step 2: Analyze each option
A is incorrect because FCFS does not optimize for similar burst times; it just queues by arrival. B is incorrect because FCFS can cause long waiting times if a long process arrives first. C is incorrect because FCFS is non-preemptive and does not handle unpredictable arrivals well. D is correct because FCFS's main advantage is simplicity and fairness in order, not responsiveness or waiting time optimization.
Final Answer:
Option D -> Option D
Quick Check:
FCFS is chosen for simplicity and fairness, not for minimizing waiting time or handling preemption.
Hint: FCFS = simple, fair order, not optimized for waiting time
3. Which of the following statements best describes a limitation of FCFS scheduling related to waiting time and system responsiveness?
medium
A. FCFS can cause long waiting times for short processes due to the convoy effect
B. FCFS guarantees the shortest average waiting time among all scheduling algorithms
C. FCFS allows preemption to improve responsiveness for interactive processes
D. FCFS scheduling complexity grows exponentially with the number of processes
Solution
Step 1: Evaluate each statement
A is correct because FCFS can cause long waiting times for short processes due to the convoy effect. B is incorrect because FCFS does not guarantee the shortest average waiting time; algorithms like SJF do. C is incorrect because FCFS is non-preemptive and does not allow preemption. D is incorrect because FCFS scheduling complexity is O(n), simple queue processing.
Step 2: Identify the limitation
The convoy effect causing long waiting times for short processes is a key limitation.
Final Answer:
Option A -> Option A
Quick Check:
FCFS is simple but can cause poor responsiveness due to the convoy effect.
Hint: FCFS = simple but convoy effect hurts short jobs
Common Mistakes:
Believing FCFS minimizes average waiting time
Confusing FCFS with preemptive algorithms
Overestimating FCFS scheduling complexity
4. Which of the following statements about the FIFO page replacement algorithm is INCORRECT?
medium
A. FIFO always evicts the least recently used page
B. FIFO can suffer from Belady's anomaly where increasing frames increases page faults
C. FIFO is simple to implement with a queue data structure
D. FIFO does not consider how frequently or recently a page was accessed
Solution
Step 1: Understand FIFO Eviction Policy
FIFO evicts the oldest loaded page, not the least recently used.
Step 2: Evaluate Each Option
FIFO can suffer from Belady's anomaly where increasing frames increases page faults is correct; Belady's anomaly can occur with FIFO. FIFO always evicts the least recently used page is incorrect; FIFO does not track recency of use. FIFO is simple to implement with a queue data structure is correct; FIFO uses a queue for eviction order. FIFO does not consider how frequently or recently a page was accessed is correct; FIFO ignores frequency and recency.
Final Answer:
Option A -> Option A
Quick Check:
FIFO evicts by arrival order, not usage recency.
Hint: FIFO evicts oldest loaded page, not least recently used [OK]
Common Mistakes:
Confusing FIFO with LRU eviction criteria
Assuming FIFO tracks page usage
Believing FIFO cannot have anomalies
5. Suppose a multithreaded application crashes due to a segmentation fault. Which of the following scenarios best explains why debugging is more challenging compared to a multi-process application?
hard
A. Because threads share the same memory, a fault in one thread can corrupt shared data, making root cause analysis harder
B. Because each thread has its own memory space, faults are isolated and easier to debug
C. Because thread context switches are slower, the fault is harder to reproduce
D. Because processes share memory, faults propagate easily between them
Solution
Step 1: Understand memory sharing in threads
Threads share the same address space, so a fault in one thread can corrupt shared data affecting others.
Step 2: Contrast with processes
Processes have isolated memory, so faults are contained, making debugging easier.
Step 3: Evaluate options
Because each thread has its own memory space, faults are isolated and easier to debug is false because threads share memory. Because thread context switches are slower, the fault is harder to reproduce is false; thread context switch speed does not affect fault reproducibility. Because processes share memory, faults propagate easily between them is false; processes do not share memory by default.
Final Answer:
Option A -> Option A
Quick Check:
Shared memory in threads complicates debugging due to data corruption [OK]
Hint: Shared memory means shared bugs [OK]
Common Mistakes:
Assuming threads have isolated memory like processes
Confusing context switch speed with debugging difficulty