Skip to content
Topic guide · Operating Systems

Processes and Threads: States, PCB, Scheduling and Deadlock · প্রসেস ও থ্রেড: অবস্থা, পিসিবি, শিডিউলিং ও ডেডলক

A process is a program in execution: the passive program (code on disk) plus its runtime state, which the OS tracks in a Process Control Block (PCB). A process moves through five states (new, ready, running, waiting, terminated), and a thread is a lightweight unit of execution inside a process that shares the process's memory but has its own stack and registers. The CPU scheduler chooses which ready process runs next (FCFS, SJF, SRTF, priority, round robin), and deadlock occurs only when all four Coffman conditions hold at once: mutual exclusion, hold and wait, no preemption, and circular wait.

প্রসেস হলো চলমান একটি প্রোগ্রাম: নিষ্ক্রিয় প্রোগ্রাম (ডিস্কে থাকা কোড) এবং তার রানটাইম অবস্থা মিলে, যা অপারেটিং সিস্টেম প্রসেস কন্ট্রোল ব্লকে (পিসিবি) রাখে। একটি প্রসেস পাঁচটি অবস্থার মধ্য দিয়ে যায় (নিউ, রেডি, রানিং, ওয়েটিং, টার্মিনেটেড); আর থ্রেড হলো প্রসেসের ভেতরের হালকা নির্বাহ-একক, যা প্রসেসের মেমরি ভাগ করে কিন্তু নিজস্ব স্ট্যাক ও রেজিস্টার রাখে। সিপিইউ শিডিউলার ঠিক করে কোন রেডি প্রসেস পরে চলবে (এফসিএফএস, এসজেএফ, এসআরটিএফ, প্রায়োরিটি, রাউন্ড রবিন); আর ডেডলক তখনই ঘটে যখন কফম্যানের চারটি শর্ত একসঙ্গে সত্য হয়: মিউচুয়াল এক্সক্লুশন, হোল্ড অ্যান্ড ওয়েট, নো প্রিএম্পশন ও সার্কুলার ওয়েট।

Asked in past exams
68
Papers
53

1. Program vs process

A program is passive: a file of instructions sitting on disk. A process is that program in execution — active, with a current value of the program counter, registers, a stack, a heap and the resources the OS has given it. One program can have many processes (open the same editor twice → two processes).

A process in memory has four segments: text (the code), data (global/static variables), heap (memory allocated at run time) and stack (function calls and local variables, growing toward the heap).

2. The Process Control Block (PCB)

For every process the OS keeps a Process Control Block, the data structure that is the process from the kernel's point of view. It holds:

  • Process ID (PID) and parent PID;
  • Process state (new, ready, running, …);
  • Program counter — the address of the next instruction;
  • CPU registers — saved so execution can resume exactly;
  • CPU-scheduling information — priority, queue pointers;
  • Memory-management information — base/limit registers, page tables;
  • Accounting — CPU time used, time limits;
  • I/O status — open files, allocated devices.

On a context switch the OS saves the running process's state into its PCB and loads the next process's state from its PCB. ("Old" is not a PCB state — the states are new, ready, running, waiting, terminated.)

3. Process states (the five-state model)

A process moves from new to ready, is dispatched to running, may be preempted back to ready or blocked into waiting, returns to ready when its event completes, and ends in terminated.
  1. New — being created; the PCB is set up but it is not yet runnable.
  2. Ready — has everything except the CPU; waiting in the ready queue.
  3. Running — executing on the CPU (only one process per core at a time).
  4. Waiting (Blocked) — cannot continue until an event (I/O, a signal, a lock) occurs; not competing for the CPU.
  5. Terminated — finished; the OS reclaims its resources.

Two transitions students wrongly draw:

  • There is no direct Waiting → Running. When I/O finishes, the process goes to Ready first and waits to be dispatched.
  • There is no direct Ready → Waiting. Only a running process can block, because only it can issue an I/O request.

A seven-state extension adds Ready/Suspended and Blocked/Suspended for processes swapped out of memory to disk. In UNIX, a finished process whose parent has not yet collected its exit status is a zombie; a process whose parent died first is an orphan.

4. Context switching

A context switch is the act of saving the state of the running process into its PCB and loading another process's state so the CPU can run it. It is pure overhead — no useful work happens during the switch — so a scheduler that switches too often wastes time. A switch is triggered by a timer interrupt (preemption), an I/O request (the process blocks), or a higher-priority process becoming ready. Thread switches within one process are cheaper than process switches because the address space (memory map) does not change.

5. Threads

A thread is a lightweight unit of execution within a process — the smallest sequence the scheduler handles. A process starts with one thread; a multithreaded process has several, running "at the same time" and sharing the process's resources.

Shared vs private. Threads of one process share the code, data/heap, and open files; each thread has its own stack, registers and program counter. Because they share memory, threads communicate cheaply (no IPC) — but that sharing is also why multithreaded programs are more prone to deadlocks and race conditions, and the main difficulty of multithreading is managing concurrency.

User-level vs kernel-level threads:

User-level threads (ULT) Kernel-level threads (KLT)
Managed by A library in user space; kernel unaware The OS kernel
Switching Fast (no kernel trap) Slower (a system call)
Blocking One blocking call blocks the whole process One thread blocks; others keep running
Multicore Cannot use multiple cores alone Can run on different cores

Multithreading models map user threads to kernel threads: Many-to-One (fast, but one block stops all; no true parallelism), One-to-One (true concurrency, one kernel thread per user thread — modern Linux and Windows), and Many-to-Many (m user to n ≤ m kernel threads, flexible).

Process vs thread — the exam table:

Aspect Process Thread
Definition Program in execution Lightweight unit inside a process
Memory Own separate address space Shares the process's address space
Creation / switch cost High (heavy) Low (light, no address-space change)
Communication IPC (pipes, sockets, shared memory) Direct, via shared variables
Fault isolation One crash does not kill others A bad thread can crash the whole process

Related terms: multiprogramming keeps several processes in memory so the CPU always has work; multitasking is time-sharing the CPU among tasks so they appear to run together; multiprocessing uses more than one CPU/core to run processes truly at the same time; multithreading runs several threads within one process.

6. fork(): counting processes

On POSIX systems (defined by The Open Group, IEEE Std 1003.1) a process creates a child with fork(). It is called once but returns twice: 0 in the child, and the child's PID in the parent. (UNIX uses fork() to create a process; there is no CreateProcess() in UNIX — that is a Windows call. fork() is POSIX, so it is not available in standard C on native Windows without a POSIX layer.)

How many processes after n consecutive forks? Each fork() doubles the number of processes, so after n calls in a row there are 2ⁿ processes in total (the original plus 2ⁿ − 1 children). Verified by running real fork() code:

Consecutive fork() calls Total processes = 2ⁿ
1 2 2¹
2 4 2²
3 8 2³
4 16 2⁴

A classic trap: how many times is a line after a loop of 3 forks printed?

for (int i = 0; i < 3; i++) {
    fork();
    printf("hi\n");
}

The print is inside the loop, so it runs once per process per remaining iteration; the total number of "hi" lines is 2¹ + 2² + 2³ = 2 + 4 + 8 = 14 — the exam answer, and what a terminal shows. (If output is redirected to a file or pipe, the same program prints 24 lines: stdout is then fully buffered, each fork() copies the unflushed "hi" lines into the child, and all 8 final processes flush 3 lines each. Calling fflush(stdout) before fork() avoids this. Both counts were confirmed by real runs.) If the printf were placed after the loop, there would be 2³ = 8 processes and 8 lines.

7. CPU scheduling (one worked example)

The scheduler picks which ready process runs next. An OS actually has three schedulers:

Scheduler Also called Decides Runs
Long-term Job scheduler Which new jobs are admitted into memory (controls the degree of multiprogramming) Rarely
Short-term CPU scheduler Which ready process gets the CPU next Very often (milliseconds)
Medium-term Swapper Which processes to swap out to disk and back (suspend/resume) Occasionally

The dispatcher is the module that actually hands the CPU to the process the short-term scheduler chose (context switch, switch to user mode, jump to the right instruction); the time it takes is the dispatch latency.

Scheduling criteria — what a good algorithm aims for: maximise CPU utilisation and throughput (processes finished per unit time); minimise turnaround time, waiting time and response time (time from arrival to the first run). The metrics used below (AT = arrival time, BT = burst time, CT = completion time):

  • Turnaround time TAT = CT − AT
  • Waiting time WT = TAT − BT

The main algorithms:

Algorithm Preemptive? Picks Note
FCFS No Earliest arrival Simple; convoy effect, high waiting time
SJF (also called Shortest Job Next, SJN) No Smallest burst Minimum average waiting time when all jobs are available together (SRTF is optimal when they arrive over time); needs the burst known; can starve long jobs
SRTF Yes Smallest remaining burst Preemptive SJF; even lower waiting; may starve
Priority Either Highest priority (in most exam questions a smaller number means higher priority) Can starve low priority → fix with aging
Round Robin Yes Next in queue, time quantum Fair, good response; overhead if the quantum is tiny
Multilevel (feedback) queue Yes Several ready queues by class or priority, each with its own algorithm In the feedback version a process that uses too much CPU moves to a lower queue, and one that waits long moves up

Worked example. Four processes:

Process Arrival (AT) Burst (BT)
P1 0 7
P2 2 4
P3 4 1
P4 5 4

Round Robin, time quantum q = 2 (a newly arrived process joins the ready queue before a just-preempted one; if the preempted process is queued first instead, the averages change to WT 5.75 and TAT 9.75 — always state the rule you use). The Gantt chart:

| P1 | P2 | P1 | P3 | P2 | P4 | P1 | P4 | P1 |
0    2    4    6    7    9    11   13   15   16

Completion times: P1 = 16, P2 = 9, P3 = 7, P4 = 15. The table (all arithmetic verified in Python):

Process AT BT CT TAT = CT − AT WT = TAT − BT
P1 0 7 16 16 9
P2 2 4 9 7 3
P3 4 1 7 3 2
P4 5 4 15 10 6
  • Average waiting time = (9 + 3 + 2 + 6) ÷ 4 = 20 ÷ 4 = 5.0
  • Average turnaround time = (16 + 7 + 3 + 10) ÷ 4 = 36 ÷ 4 = 9.0

For the same four processes, the verified averages under the other algorithms are: FCFS avg WT 4.75; SJF (non-preemptive) avg WT 4.0; SRTF avg WT 3.0 (the lowest, as SJF-type scheduling minimises average waiting time). Note which algorithms can cause starvation: SJF (Shortest Job Next), SRTF and priority (a steady stream of short or high-priority jobs can indefinitely delay a long or low-priority one); FCFS and round robin cannot starve.

8. Deadlock: the Coffman conditions

A deadlock is a set of processes each waiting for a resource held by another in the set, so none can proceed. It needs all four Coffman conditions at once:

  1. Mutual exclusion — a resource can be held by only one process at a time.
  2. Hold and wait — a process holding at least one resource is waiting for more.
  3. No preemption — a resource cannot be forcibly taken; it is released only voluntarily.
  4. Circular wait — a closed chain of processes, each waiting for a resource the next one holds.
Circular wait: process P1 holds resource R1 and wants R2, while P2 holds R2 and wants R1, so neither can proceed.

Break any one condition and deadlock cannot occur — the basis of deadlock prevention. The four conditions are necessary but not sufficient: in a resource-allocation graph, a cycle means deadlock if every resource has a single instance; with multiple instances a cycle is necessary but not sufficient. A single process on its own cannot deadlock, because circular wait needs at least two (in the classic Coffman sense; a thread can still hang itself by re-locking a non-reentrant mutex it already holds). Handling strategies: prevention (deny a condition), avoidance (the Banker's algorithm keeps the system in a safe state), detection and recovery, and the ostrich algorithm (ignore it, as general-purpose OSes mostly do).

A resource-counting result that exams ask: if n processes each need at most m units of a resource with R identical units, the system is deadlock-free as long as n × (m − 1) + 1 ≤ R (give every process m − 1 and one unit is still spare to let someone finish). For example, with R = 6 units and each process needing at most m = 3, up to n = 2 processes are guaranteed deadlock-free (2 × 2 + 1 = 5 ≤ 6), but n = 3 can deadlock — verified by brute-force search.

9. The critical section (in brief)

A critical section is the part of a program that accesses a shared resource and must not run in two processes at once. A correct solution needs three properties: mutual exclusion (at most one process inside), progress (if no one is inside, a waiting process can enter), and bounded waiting (no process waits forever). It is enforced with locks/mutexes, semaphores (Dijkstra's wait/signal), or monitors. A binary semaphore takes only 0 or 1 and works like a lock; a counting semaphore holds any non-negative value and controls access to a pool of identical resources (for example 5 printer slots). Mishandled locks are exactly how the circular-wait condition for deadlock arises.

Practice · অনুশীলন

  1. Differentiate a process from a thread (two points).
    Answer

    A process has its own separate address space and is heavy to create and switch; a thread shares its process's address space, is lightweight, and switches faster. Threads communicate directly via shared memory, whereas processes need IPC.

  2. Why is there no direct Waiting → Running transition?
    Answer

    When the awaited event (e.g. I/O) completes, the process becomes runnable but the CPU may be busy, so it must join the ready queue and wait for the dispatcher. The path is Waiting → Ready → Running.

  3. How many processes exist in total after 3 consecutive fork() calls?
    Answer

    2³ = 8 processes (the original plus 7 children); each fork() doubles the count.

  4. List the four Coffman conditions for deadlock. Can a single process deadlock?
    Answer

    Mutual exclusion, hold and wait, no preemption, and circular wait — all four must hold. A single process alone cannot deadlock, because circular wait needs at least two processes.

  5. Which scheduling algorithms can cause starvation?
    Answer

    SJF (Shortest Job Next), SRTF and priority scheduling (a stream of short or high-priority jobs can indefinitely delay others). Aging fixes priority starvation. FCFS and round robin do not starve.

Asked in past exams · আগের পরীক্ষায় যেভাবে এসেছে

Our past papers have 68 questions on this topic (26 MCQ, 42 written) from 53 exams. Here are 12 of them; each links to its full paper.

  1. What is Multithreading System?

    Model answer on the paper page

  2. Explain how can multiprogramming be achieved on a uniprocessor system?

    Model answer on the paper page

  3. Explain the process state.

    Model answer on the paper page

  4. Explain context switching in Operating System.

    Model answer on the paper page

  5. What is Deadlock? Explain two situations where deadlock condition occurs.

    Model answer on the paper page

  6. What is Multi-threading and multi-tasking? Difference between Multi-threading and Multi-tasking?

    Model answer on the paper page

  7. In Unix operating system, which system call is used for creating a new process?

    • a)Exec()
    • b)Create Process()
    • c)Fork() (correct answer)
    • d)None of them
    Explanation · ব্যাখ্যা

    Correct answer: (c) Fork()

    In UNIX the fork() system call creates a new process. The new (child) process is a near-copy of the calling (parent) process.

    A classic check: a program that calls fork() twice in a row ends up with 4 processes, the original plus 3 children (2² = 4).

    Why the other options are wrong

    • (a) Exec(): the exec family replaces the current process image with a new program, so no new process is created. The usual pattern is fork() first, then exec() in the child.
    • (b) Create Process(): CreateProcess() belongs to the Windows API; UNIX has no system call by that name.
    • (d) None of them: wrong, because (c) is exactly the UNIX call that creates a process.

    Exam note: Only the spacing before "()" in options (b) and (c) has been fixed.

    Tip: fork() = new process; exec() = new program inside the same process.

    Source: fork — The Open Group Base Specifications; exec — The Open Group Base Specifications

  8. What is the disadvantage of multithreading?

    • a)Share the same address space
    • b)Simultaneous access to multiple applications
    • c)Low cost communication
    • d)Difficulty in managing concurrency (correct answer)
    Explanation · ব্যাখ্যা

    Correct answer: (d) Difficulty in managing concurrency

    Threads of one process run concurrently over the same memory, so a shared variable can be read and written by several threads at once. Without careful synchronisation (locks, mutexes, atomic operations) the program suffers race conditions, where the result depends on which thread gets there first, and deadlocks, where threads wait for each other's locks forever. Such bugs depend on timing, so they are hard to reproduce and debug. That is the main price paid for multithreading.

    Why the other options are wrong

    • (a) Share the same address space: sharing memory is a key benefit of threads: data is shared without copying and without setting up IPC.
    • (b) Simultaneous access to multiple applications: doing several activities at the same time (responsiveness, parallelism on multicore CPUs) is the purpose of multithreading, an advantage.
    • (c) Low cost communication: threads communicate through shared memory, far cheaper than inter-process communication; an advantage.

    Exam note: Option (b) is repaired from "multiple application" to "multiple applications" (grammar only).

    Tip: Threads buy speed and cheap sharing; the price is synchronisation complexity.

    Source: Managed threading best practices — Microsoft Learn

  9. What is multitasking and multithreading? What are the advantage threads over process?

    Model answer on the paper page

  10. Which of the following process scheduling algorithm may lead to starvation?

    • a)FIFO
    • b)Round Robin
    • c)Shortest Job Next (correct answer)
    • d)None of these
    Explanation · ব্যাখ্যা

    Correct answer: (c) Shortest Job Next

    Shortest Job Next (another name for Shortest Job First) always runs the waiting job with the shortest CPU burst; it is priority scheduling with priority = 1 / next CPU burst, so long jobs get the lowest priority. If short jobs keep arriving, a long job is passed over again and again and may never get the CPU. This indefinite postponement is starvation. The usual cure is aging: raising a job's priority the longer it waits.

    Why the other options are wrong

    • (a) FIFO: the same as FCFS; jobs are served strictly in arrival order, so each one is reached after the finite number of jobs ahead of it. Waits may be long, but there is no starvation.
    • (b) Round Robin: every ready process gets a time quantum in turn, so with n ready processes and quantum q nobody waits more than (n − 1) × q for the next turn. No starvation.
    • (d) None of these: wrong because SJN can starve long jobs.

    Tip: Starvation-prone: SJF/SJN, SRTF, Priority. Starvation-free: FCFS/FIFO, Round Robin.

    Source: Chapter 2: Process Scheduling (EE442 Operating Systems, METU)

  11. Multi-Threaded programs are-

    • a)Less prone to deadlocks
    • b)more prone to deadlocks (correct answer)
    • c)not at all prone to deadlock
    • d)always result in deadlocks
    Explanation · ব্যাখ্যা

    Correct answer: (b) more prone to deadlocks

    A deadlock needs several agents that each hold a resource while waiting for one held by another, closing a cycle (mutual exclusion, hold-and-wait, no preemption, circular wait). A multi-threaded program creates exactly this setting: several threads run at once and acquire shared locks, often in different orders. If thread T1 holds lock A and waits for B while T2 holds B and waits for A, both stop forever. A single-threaded program has no second thread to complete such a cycle, so adding threads makes deadlock possible and more likely.

    Why the other options are wrong

    • (a) Less prone to deadlocks: more threads and more locks mean more chances of a circular wait, not fewer.
    • (c) not at all prone to deadlock: the two-lock example above shows that multi-threaded code can deadlock.
    • (d) always result in deadlocks: deadlock occurs only for certain lock orders and timings; well-designed code (for example, acquiring locks in one fixed global order) never deadlocks.

    Exam note: Options (a) and (d) are repaired for grammar only ("Lesser" → "Less", "results" → "result").

    Tip: Threads + shared locks ⇒ deadlock becomes possible; a fixed lock order breaks circular wait.

    Sources: Deadlock — CS 3130, University of Virginia; Managed threading best practices — Microsoft Learn

  12. (a) Differentiate between process and thread.

Common mistakes · সাধারণ ভুল

  • Calling a program and a process the same thing: a program is passive code on disk; a process is a program in execution with state.
  • Drawing a direct Waiting → Running or Ready → Waiting transition: neither exists in the five-state model.
  • Listing 'Old' as a process/PCB state: the states are new, ready, running, waiting, terminated.
  • Saying fork() gives n processes for n calls: it gives 2ⁿ because every fork doubles the count.
  • Computing WT = CT − BT: the correct formula is WT = TAT − BT = CT − AT − BT.
  • Claiming any one Coffman condition causes deadlock: all four must hold simultaneously; breaking one prevents deadlock.

বাংলায় সংক্ষেপে

  • প্রোগ্রাম নিষ্ক্রিয় কোড, প্রসেস হলো চলমান প্রোগ্রাম; অপারেটিং সিস্টেম প্রতিটি প্রসেসের তথ্য রাখে পিসিবিতে (PID, অবস্থা, প্রোগ্রাম কাউন্টার, রেজিস্টার)।
  • পাঁচ অবস্থা: নিউ, রেডি, রানিং, ওয়েটিং, টার্মিনেটেড; ওয়েটিং থেকে সরাসরি রানিং-এ যাওয়া যায় না, আগে রেডিতে যেতে হয়।
  • থ্রেড প্রসেসের মেমরি ভাগ করে (কোড, ডেটা, ফাইল) কিন্তু নিজস্ব স্ট্যাক ও রেজিস্টার রাখে; তাই থ্রেড হালকা ও দ্রুত কিন্তু কনকারেন্সি ব্যবস্থাপনা কঠিন।
  • fork() প্রতিবার প্রসেস দ্বিগুণ করে; n বার কল করলে মোট ২ⁿ প্রসেস; fork() পজিক্স (POSIX) কল।
  • শিডিউলিং: TAT = CT − AT, WT = TAT − BT; SJF/SRTF গড় অপেক্ষাকাল সবচেয়ে কম কিন্তু SJF (শর্টেস্ট জব নেক্সট), SRTF ও প্রায়োরিটিতে স্টারভেশন হতে পারে।
  • ডেডলকের চারটি কফম্যান শর্ত একসঙ্গে লাগে: মিউচুয়াল এক্সক্লুশন, হোল্ড অ্যান্ড ওয়েট, নো প্রিএম্পশন, সার্কুলার ওয়েট; যেকোনো একটি ভাঙলে ডেডলক হয় না।

Updated 2026-10-18. Written by ARBS Academy; the past exam questions are from public recruitment exams.