Threads
10. What is a thread, and how does it differ from a process?
Thread হলো একটি process-এর ভেতরে execution-এর সবচেয়ে ছোট unit। একটি process-এ একটি বা একাধিক thread থাকতে পারে। প্রতিটি thread-এর ন িজস্ব execution flow থাকে, তবে তারা একই process-এর code, data, heap, open files ইত্যাদি resource share করে।
Thread-কে অনেক সময় lightweight process বলা হয়, কারণ এটি process-এর মতো execution করে, কিন্তু সাধারণত নিজস্ব আলাদা address space তৈরি করে না। বরং একই process-এর resources share করে। এই কারণে thread তৈরি ও একই process-এর threadগুলোর মধ্যে context switch করা process-এর তুলনায় সাধারণত কম খরচসাপেক্ষ।
Single-threaded vs Multi-threaded Process
PreviewClick to view details
Single-threaded Process: Multi-threaded Process:
┌───────────────────┐ ┌───────────────────────────┐
│ Process │ │ Process │
│ ┌─────────────┐ │ │ ┌───────┐ ┌───────┐ │
│ │ Thread │ │ │ │Thread │ │Thread │ ... │
│ │ (single) │ │ │ │ T1 │ │ T2 │ │
│ └─────────────┘ │ │ └───────┘ └───────┘ │
│ │ │ │
│ Code, Data, │ │ Code, Data, Files, Heap │
│ Files, Heap │ │ (সব thread share করে) │
└───────────────────┘ └───────────────────────────┘
Thread এবং Process-এর পার্থক্য
| বিষয় | Process | Thread |
|---|---|---|
| সংজ্ঞা | একটি চলমান program-এর instance | Process-এর ভেতরে execution unit |
| Memory | নিজস্ব virtual address space থাকে; explicit shared mapping থাকতে পারে | একই process-এর virtual address space share করে |
| তৈরির খরচ | বেশি | কম |
| Communication | IPC লাগে (pipe, socket, message queue ইত্যাদি) | Shared memory-এর মাধ্যমে সহজে data share করা যায় |
| Isolation | এক process অন্য process থেকে আলাদা | একই process-এর thread গুলো একে অপরকে প্রভাবিত করতে পারে |
| Context switch | তুলনামূলক ধীর ও ব্যয়বহুল | তুলনামূলক দ্রুত |
| Crash effect | একটি process crash করলে সাধারণত অন্য process সরাসরি প্রভাবিত হয় না | একটি thread-এ গুরুতর error হলে পুরো process প্রভাবিত বা terminate হতে পারে |
What resources are shared between threads of the same process, and what is private to each thread?
Thread বোঝার জন্য এটি সবচেয়ে গুরুত্বপূর্ণ অংশ।
Shared — একই process-এর সব thread share করে
একই process-এর ভেতরে থাকা সব thread নিচের resource গুলো share করে:
- Code / Text segment
- Data segment (global/static variables)
- Heap (dynamic memory)
- Open files / file descriptors
- Process address space
- Signal disposition/handlers ও process-level attributes সাধারণত process-wide হিসেবে shared থাকে; তবে signal mask ও কিছু pending-signal state per-thread হতে পারে
PreviewClick to view details
┌─────────────────────────────────────────┐
│ Process Memory │
│ │
│ ┌───────────────────────────────────┐ │
│ │ Code Segment │ │ ← একই code সবাই ব্যবহার করে
│ └───────────────────────────────────┘ │
│ ┌───────────────────────────────────┐ │
│ │ Data Segment │ │ ← Global / static data shared
│ └───────────────────────────────────┘ │
│ ┌───────────────────────────────────┐ │
│ │ Heap │ │ ← Dynamic memory shared
│ │ (malloc / new এর memory) │ │
│ └───────────────────────────────────┘ │
│ ┌───────────────────────────────────┐ │
│ │ Open File Descriptors │ │ ← একই files access করতে পারে
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘
Private — প্রতিটি thread-এর নিজস্ব
প্রতিটি thread-এর কিছু নিজস্ব execution-related state থাকে:
- Thread ID
- Program Counter (PC)
- CPU Registers
- Stack
- Local variables / function call information
- Thread-local storage (TLS) এবং কিছু per-thread signal/scheduling state
প্রতিটি thread-এর stack আলাদা হলেও সেটি একই process address space-এর অংশ। তাই stack/local data automatically memory-isolated নয়—valid pointer পেলে অন্য thread সেটি access করতে পারে।
PreviewClick to view details
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Thread 1 │ │ Thread 2 │ │ Thread 3 │
│ │ │ │ │ │
│ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │
│ │ Stack │ │ │ │ Stack │ │ │ │ Stack │ │
│ │ (local │ │ │ │ (local │ │ │ │ (local │ │
│ │ vars, │ │ │ │ vars, │ │ │ │ vars, │ │
│ │ calls) │ │ │ │ calls) │ │ │ │ calls) │ │
│ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │
│ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │
│ │Program │ │ │ │Program │ │ │ │Program │ │
│ │Counter │ │ │ │Counter │ │ │ │Counter │ │
│ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │
│ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │
│ │ CPU │ │ │ │ CPU │ │ │ │ CPU │ │
│ │Registers │ │ │ │Registers │ │ │ │Registers │ │
│ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │
│ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │
│ │Thread ID │ │ │ │Thread ID │ │ │ │Thread ID │ │
│ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │
└── ────────────┘ └──────────────┘ └──────────────┘
Why is creating a thread generally cheaper than creating a process?
Thread process-এর তুলনায় সস্তা হওয়ার মূল কারণ হলো — thread-এর জন্য পুরো নতুন execution environment তৈরি করতে হয় না।
আলাদা address space তৈরি করতে হয় না
নতুন process তৈরি করলে OS-কে সাধারণত একটি নতুন address space, process metadata, page table, memory management structure ইত্যাদি সাম লাতে হয়।
কিন্তু নতুন thread তৈরি করলে সাধারণত:
- একই process-এর code
- data
- heap
- open files
এগুলো নতুন করে তৈরি করতে হয় না। শুধু নতুন thread-এর জন্য মূলত stack এবং thread control information তৈরি করতে হয়।
PreviewClick to view details
নতুন Process তৈরিতে: নতুন Thread তৈরিতে:
┌──────────────────────┐ ┌──────────────────────┐
│ নতুন address space │ │ address space shared │
│ নত ুন page table │ │ code/data shared │
│ নতুন process info │ │ heap shared │
│ নতুন stack │ │ নতুন stack │
│ নতুন PCB │ │ নতুন TCB │
└──────────────────────┘ └──────────────────────┘
Memory overhead কম
Process-এর জন্য পুরো নতুন memory space management দরকার হতে পারে। Thread-এর ক্ষেত্রে আলাদা পুরো memory space লাগে না, কারণ thread একই process-এর resources share করে।
তাই:
- memory allocation overhead কম
- memory management overhead কম
- resource duplication কম
Context switch তুলনামূলক দ্রুত
Process context switch-এ OS-কে সাধারণত:
- CPU registers save/restore করতে হয়
- process state বদলাতে হয়
- memory management context change করতে হয়
- address space switch করতে হয়
কিন্তু একই process-এর দুই thread-এর মধ্যে context switch হলে address space একই থাকে। তাই ভিন্ন process-এর thread-এ switch করার তুলনায় memory-management overhead কম হতে পারে, ফলে একই process-এর thread switch সাধারণত দ্রুত হয়। এটি absolute guarantee নয়; actual cost OS, architecture ও cache state-এর ওপর নির্ভর করে।
PreviewClick to view details
Process Context Switch: Thread Context Switch:
┌────────────────────────┐ ┌────────────────────────┐
│ Registers save │ │ Registers save │
│ Address space switch │ │ Same address space │
│ Memory context change │ │ কম overhead │
│ Registers restore │ │ Registers restore │
└────────────────────────┘ └────────────────────────┘
Communication সহজ ও দ্রুত
দুটি process যদি একে অপরের সাথে data exchange করতে চায়, তাহলে সাধারণত IPC (Inter-Process Communication) ব্যবহার করতে হয়, যেমন:
- pipe
- socket
- shared memory
- message queue
এ গুলো তুলনামূলক complex হতে পারে।
কিন্তু একই process-এর thread গুলো যেহেতু একই memory share করে, তাই data আদান-প্রদান অনেক সহজ হয়। যেমন একটি global variable, shared buffer, shared object ইত্যাদি ব্যবহার করে thread গুলো communicate করতে পারে।
PreviewClick to view details
Process-এ Communication (IPC): Thread-এ Communication:
Process A Process B Thread 1 Thread 2
│ │ │ │
│──Pipe/──────►│ │◄─ Shared ─►│
│ Socket/ │ │ Memory │
│ Queue │ │ │
(more complex) (faster, simpler)
তবে shared memory ব্যবহারের সময় synchronization না করলে race condition হতে পারে।
ধরো একটি web server process আছে। সেখানে একাধিক thread থাকতে পারে:
- Thread 1 → নতুন client request accept করছে
- Thread 2 → database query handle করছে
- Thread 3 → log লিখছে
- Thread 4 → background task করছে
এভাবে একই process-এর ভেতরে একাধিক thread একসাথে কাজ করলে application আরও responsive এবং efficient হতে পারে।
আরও একটি উদাহরণ: একটি application-এর মধ্যে:
- একটি thread UI handle করছে
- আরেকটি thread network request handle করছে
- আরেকটি thread file download করছে
ফলে UI freeze না হয়ে application responsive থাকতে পারে।
Thread-এর সুবিধা
Responsiveness: একটি thread block হলেও অন্য thread কাজ চালিয়ে যেতে পারে — যদি OS/kernel সেই thread-গুলোকে আলাদা scheduling entity হিসেবে handle করতে পারে। যেমন UI thread আলাদা থাকলে background download চলার সময়ও application responsive থাকতে পারে।
Resource sharing: একই process-এর thread গুলো shared memory ব্যবহার করে সহজে data share করতে পারে।
Economy: Thread তৈরি, terminate করা এবং context switch করা process-এর তুলনায় কম খরচসাপেক্ষ।
Scalability / Parallelism: Multi-core CPU থাকলে একাধিক thread সত্যিকারের parallel execution পেতে পারে — যদি underlying threading model ও OS support তা allow করে।
Thread-এর সমস্যা
Race Condition: দুটি বা তার বেশি thread একই shared data একসাথে modify করলে unexpected result হতে পারে।
Deadlock: একাধিক thread যদি একে অপরের resource release-এর জন্য অপেক্ষা করতে থাকে, তাহলে তারা আটকে যেতে পারে।
Synchronization Complexity: Shared data safe রাখার জন্য mutex, semaphore, lock ইত্যাদি ব্যবহার করতে হয়। এগুলো ভুলভাবে ব্যবহার করলে bug হতে পারে।
Debugging কঠিন: Concurrent program-এ bug reproduce করা কঠিন হতে পারে, কারণ timing-এর উপর behavior বদলে যেতে পারে।
একটি thread-এর গুরুতর error পুরো process-কে প্রভাবিত করতে পারে: যেহেতু thread গুলো একই process-এর memory space share করে, তাই memory corruption বা segmentation fault-এর মতো error পুরো process-কে ক্ষতিগ্রস্ত করতে পারে।
11. What is the difference between user-level threads and kernel-level threads?
মূল প্রশ্ন: OS কি thread-এর অস্তিত্ব জানে?
User-level threads এবং kernel-level threads-এর পার্থক্যের মূল ভিত্তি হলো:
OS kernel কি প্রতিটি thread-এর অস্তিত্ব জানে, নাকি জানে না?
PreviewClick to view details
User-level Thread (ULT): Kernel-level Thread (KLT):
User Space User Space
┌────────────── ───┐ ┌─────────────────┐
│ Thread Library │ │ Application │
│ T1 T2 T3 │ │ T1 T2 T3 │
│ (OS জানে না) │ │ │
└────────┬────────┘ └──┬───┬───┬──────┘
│ (একটি scheduling entity) │ │ │
─────────┼─────────────────────── ───┼───┼───┼────────
Kernel │ Kernel │ │ │
┌────────┴────────┐ ┌──┴───┴───┴──────┐
│ Process P │ │ KT1 KT2 KT3 │
│ Kernel-এর কাছে │ │ OS সবাইকে জানে │
│ একটাই entity │ │ │
└─────────────────┘ └─────────────────┘
User-Level Threads (ULT)
User-level thread হলো এমন thread যাকে user space-এর thread library manage করে। Pure many-to-one ULT model-এ thread তৈরি, user-thread scheduling, resume এবং user-thread context switch মূলত user space-এ হয়। Many-to-many runtime-এ underlying kernel thread management বা blocking operation-এর জন্য kernel interaction লাগতে পারে।
Kernel সাধারণত জানে না যে ওই process-এর মধ্যে একাধিক user thread আছে। Many-to-one model-এ kernel-এর কাছে পুরো process-টি একটি single schedulable entity হিসেবে দেখা যায়। তবে বাস্তবে ULT/KLT behavior mapping model-এর ওপর নির্ভর করে, যা পরের section-এ এসেছে।
ULT কীভাবে কাজ কর ে
PreviewClick to view details
User Space:
┌────────────────────────────────────────────┐
│ Thread Library │
│ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │Thread 1│ │Thread 2│ │Thread 3│ │
│ │(Ready) │ │(Run) │ │(Wait) │ │
│ └────────┘ └────────┘ └────────┘ │
│ │
│ Library নিজেই scheduling করে │
│ Library নিজেই context switch করে │
└──────────────────┬─────────────────────────┘
│
═══════════════════╪════════════════════════════
Kernel Space: │
┌────┴───────┐
│ Process P │
│ Kernel-এর │
│ কাছে একটাই │
│ entity │
└────────────┘
ULT-এ সাধারণত:
- thread library ready queue maintain করে
- কোন thread run করবে তা library ঠিক করে
- context switch library code-এর মাধ্যমেই হয়
- kernel শুধু পুরো process-টিকে schedule করে
Kernel-Level Threads (KLT)
Kernel-level thread হলো এমন thread যাকে OS kernel সরাসরি manage করে। প্রতিটি thread OS-এর কাছে আলাদা scheduling entity হিসেবে পরিচিত থাকে। Kernel সরাসরি প্রতিটি thread-কে CPU দিতে পারে।
PreviewClick to view details
User Space:
┌────────────────────────────────────────────┐
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │Thread 1│ │Thread 2│ │Thread 3│ │
│ └───┬────┘ └───┬────┘ └───┬────┘ │
└──────┼───────────┼───────────┼────────────┘
│ system │ system │ system
│ call │ call │ call
═══════╪═══════════╪═══════════╪════════════
Kernel:│ │ │
┌────┴──┐ ┌────┴──┐ ┌───┴───┐
│ KT1 │ │ KT2 │ │ KT3 │
└───────┘ └───────┘ └───────┘
Kernel প্রতিটি thread আলাদাভাবে schedule করে
ULT বনাম KLT — মূল পার্থক্য
| বিষয় | ULT | KLT |
|---|---|---|
| OS thread সম্পর্কে জানে? | সাধারণত না | হ্যাঁ |
| কে manage করে? | User-space thread library | Kernel |
| Scheduling কে করে? | Library | Kernel |
| Context switch | দ্রুত হতে পারে | তুলনামূলক ব্যয়বহুল |
| Thread block হলে | অনেক ক্ষেত্রে পুরো process block হতে পারে | শুধু ঐ thread block হয় |
| Multi-core parallelism | সীমিত / model-নির্ভর | সম্ভব |
| Kernel features | সরাসরি সব সুবিধা পায় না | Kernel scheduling, priority, signals ইত্যাদি পায় |
What are the advantages and disadvantages of each?
ULT-এর সুবিধা
i. Thread তৈরি ও switch দ্রুত
ULT context switch user space-এ হওয়ায় system call ছাড়াই হতে পারে।
PreviewClick to view details
ULT context switch:
Library function call
→ registers save
→ next thread নির্বাচন
→ registers restore
(অনেক ক্ষেত্রে kernel involvement লাগে না)
ii. Portable
Thread library অনেক OS-এ চলতে পারে। তাই implementation তুলনামূলক portable হতে পারে।
iii. Custom scheduling সম্ভব
Application নিজেই তার দরকারমতো scheduling policy ব্যবহার করতে পারে।
iv. Kernel resource কম লাগে
যদি kernel প্রতিটি user thread-এর জন্য আলাদা kernel structure না রাখে, তাহলে অনেক ULT তৈরি করা তুলনামূলক সস্তা হতে পারে।
ULT-এর অসুবিধা
i. একটি blocking operation পুরো process-কে আটকে দিতে পারে
যদি threading model many-to-one ধরনের হয় এবং একটি thread blocking system call করে, তাহলে kernel পুরো process-টিকেই block করে ফেলতে পারে।
PreviewClick to view details
T1 block (I/O wait):
┌─────────────────────────────┐
│ T1 (blocked - file read) │
│ T2 (ready - কিন্তু আটকা) │
│ T3 (ready - কিন্তু আটকা) │
└─────────────────────────────┘
ii. True parallelism সীমিত হতে পারে
যদি kernel একটিমাত্র scheduling entity দেখে, তাহলে multi-core CPU-র full সুবিধা পাওয়া যায় না।
iii. Kernel scheduling সুবিধা সরাসরি পাওয়া যায় না
Kernel প্রতিটি thread-কে আলাদা entity হিসেবে না দেখলে per-thread priority বা kernel-level scheduling সুবিধা সী মিত হয়।
KLT-এর সুবিধা ও অসুবিধা
সুবিধা
i. True parallelism সম্ভব
Kernel প্রতিটি thread-কে আলাদা entity হিসেবে দেখে, তাই multi-core CPU-তে একাধিক thread একসাথে চলতে পারে।
Multi-core CPU:
Core 1 → KT1
Core 2 → KT2
Core 3 → KT3
ii. একটি thread block হলেও অন্যরা চলতে পারে
একটি kernel thread blocked হলেও kernel অন্য ready thread-কে schedule করতে পারে।
PreviewClick to view details
T1 block (I/O wait):
┌──────────────────────────────────┐
│ KT1 (blocked) │
│ KT2 (running) ✓ │
│ KT3 (running) ✓ │
└──────────────────────────────────┘
iii. Kernel-এর scheduling সুবিধা পাওয়া যায়
Priority scheduling, CPU accounting, signals, real-time support ইত্যাদি সুবিধা thread-level-এ পাওয়া যায়।
অসুবিধা