4.2.29 · Coding › Operating Systems
Intuition Aalsi librarian wali kahani
Socho do students ek hi book chahte hain. Ek faaltu librarian dusre student ke liye turant poori book ki photocopy kar deta hai. Ek aalsi librarian dono students ko ek hi copy access karta hai, aur page ki photocopy tabhi karta hai jab koi us par kuch likhne ki koshish kare .
Copy-on-write exactly yahi hai: memory share karo jab tak koi write na kare, phir sirf wahi page copy karo jo modify ho raha hai . Hum mehenga copying delay karte hain (aur often bilkul avoid kar lete hain).
Ek resource-management technique jisme multiple consumers ek single physical copy of data share karte hain jo read-only mark hoti hai. Jab koi consumer isse modify karne ki koshish karta hai, system write trap karta hai, sirf affected unit (memory page ) ki private copy banata hai, writer ki mapping update karta hai, aur write aage proceed hone deta hai. Jo readers kabhi write nahi karte, unke liye copy kabhi trigger nahi hoti .
OS memory mein copying ki "unit" page hoti hai (typically 4 KB ). Trigger mechanism ek page fault hai jo read-only mark page par write karne se hota hai.
Yahan milta hai yeh:
fork() — child parent ka address space share karta hai jab tak koi write na kare.
mmap(... MAP_PRIVATE) — file pages shared rehte hain jab tak write na ho.
Filesystems (ZFS, Btrfs) aur VM memory mein snapshots.
fork()-then-exec() ki barbadi
Classic Unix: ek shell fork() karta hai child banane ke liye, phir child turant exec() call karta hai apni poori memory ko naye program se replace karne ke liye. Agar fork() eagerly pura address space copy karta (ho sakta hai gigabytes!) toh woh copy microseconds baad exec() se phek di jaati . Bilkul bekar.
COW fork() ko shuruaat mein kuch bhi copy nahi karne deta — sirf page tables — toh throwaway lagbhag kuch nahi cost karta.
Do fayde:
Speed : fork() O ( number of pages ) ban jaata hai table setup ke liye, data copy ke liye O ( memory size ) nahi.
Memory : pages shared (deduplicated) rehte hain jab tak koi write na kare — bahut achha jab kai processes read-only code/data share karte hain.
Jab ek process duplicate hoti hai (e.g. fork()):
Child ko apne page tables milte hain, lekin har entry same physical frames point karti hai jo parent ke hain.
Saare shared writable pages dono page tables mein read-only mark ho jaate hain, aur internally COW flag ho jaate hain.
OS har physical frame ka reference count track karta hai: kitne mappings usse share kar rahe hain.
Reading? Theek hai — read-only reads allow karta hai. Koi fault nahi, koi copy nahi.
COW page par write karna → CPU page fault raise karta hai (read-only page par write).
Fault handler check karta hai: "Kya yeh COW page hai?" Haan →
Ek naya frame allocate karo, purani page ka content usmein copy karo.
Writer ka PTE naye frame ki taraf point karo, use writable mark karo, purane frame ka refcount kam karo.
Agar purana refcount 1 tak girta hai, toh remaining owner ka page phir se writable banaya ja sakta hai (use COW rakhne ki zarurat nahi).
Faulting instruction dobara execute karo; ab write private copy par hoti hai.
fork() phir ek single write — Har step kyun?
Parent ke paas 3 pages hain: code C, data D, stack S.
fork(): child ke tables C, D, S point karte hain; sab read-only + COW mark; refcounts = 2 each.
Kyun? Abhi kuch copy karne se bachna — shayad koi likhta hi nahi.
Child chalta hai, code C baar baar read karta hai. Koi copy nahi hoti.
Kyun? Read-only pages par reads allowed hain; sharing safe hai.
Child page D mein ek variable likhta hai → page fault.
Kyun? D ko read-only is liye mark kiya tha taaki pehla write pakda jaa sake.
Handler D → D′ copy karta hai, child ka D entry ab D′ (writable) point karta hai. refcount(D) → 1.
Kyun? Sirf changed page duplicate hoti hai; C aur S abhi bhi shared hain.
Result: 3 ki jagah 1 page copy hua. Baaki ki memory aur time bach gayi.
Common mistake "Fork ke baad, parent aur child
same variables share karte hain — writes dono ko visible hote hain."
Kyun lagta hai sahi: woh literally shuruaat mein same physical frames point karte hain, toh lagta hai shared hai.
Fix: sharing read-only hai. Pehla write copy ke zariye share tod deta hai . Uske baad writer ko ek private copy milti hai. Toh fork() independent address spaces deta hai — COW ek implementation optimization hai, program semantics ko dikhta nahi.
Common mistake "COW har write par copy karta hai."
Kyun lagta hai sahi: naam kehta hai "on write."
Fix: yeh har shared page par pehli write par copy karta hai. Jab page private ho jaata hai (refcount 1, writable), aage ke writes seedha use touch karte hain — aur koi fault nahi .
Common mistake "COW hamesha time bachata hai."
Kyun lagta hai sahi: kaam defer karna free lagta hai.
Fix: agar ek process har page likhta hai (W = N ), toh table setup plus saari copies plus per-page fault overhead pay karna padta hai — eager copy se thoda zyada bura. COW bet lagata hai ki W ≪ N , jo usually sach hota hai.
Common mistake "Read-only marking sirf child ko affect karti hai."
Kyun lagta hai sahi: child 'naya' process hai.
Fix: dono parent aur child entries read-only mark hote hain. Agar parent pehle likhta hai, woh fault karta hai aur copy leta hai. COW symmetric hai.
Recall Feynman: 12 saal ke bacche ko samjhao
Tum aur tumhara dost dono ek hi comic padhna chahte ho. Do comics khareedne ki jagah, tum ek ek share karte ho. Rule yeh hai: koi usmein kuch nahi likha. Jis waqt tum kisi character par moochh banana chahte ho, tum copier par bhaago, sirf woh page copy karo, apni copy par moochh banao, aur shared comic ko apne dost ke liye saaf chod do. Tumne poori comic kabhi copy nahi ki — sirf woh ek page jo change karna tha. Yehi copy-on-write hai: share karo jab tak change na karo, phir sirf changed part copy karo.
"Share, Mark, Fault, Copy, Continue."
Ya ek asli COW 🐄 socho: woh aalsi hai, copies nahi banayegi jab tak tum use pocho (write) na. Aur R ead-O nly woh fence hai — isse paar karo (write karo) aur woh ek bacchaa (naya page) alag kar deti hai.
Copy-on-write kya hai? Ek technique jisme multiple consumers data ki ek read-only physical copy share karte hain; pehla write sirf affected page ki copy trigger karta hai, jiske baad writer ke paas private copy hoti hai.
OS-level COW mein copying ki unit kya hoti hai? Ek memory page (typically 4 KB).
COW write ko kaunsa hardware mechanism detect karta hai? Ek page fault, jo isliye raise hota hai kyunki shared page read-only mark hoti hai.
fork() COW kyun use karta hai?Pura address space eagerly copy karna bekar hai (aksar turant exec() se phek diya jaata hai); COW shuruaat mein kuch copy nahi karta aur sirf woh pages duplicate karta hai jo actually likhe jaate hain.
Fork ke baad, shared pages read-only kaun mark karta hai — child ya dono? Dono parent aur child, taaki jo bhi pehle likhe woh copy trigger kare.
COW time cost formula kya hai? T co w = N c t + W c c , jahan N =pages, W =written pages, c t =table-entry cost, c c =page-copy cost.
COW eager copying se worse kab hota hai? Jab lagbhag har page likha jata hai (W ≈ N ), kyunki table setup + saari copies + per-page fault overhead pay karna padta hai.
COW mein reference count kya track karta hai? Kitne mappings abhi ek diye gaye physical frame ko share kar rahe hain.
COW page copy hone ke baad aur refcount 1 hone par kya hota hai? Remaining owner ka page phir se writable banaya ja sakta hai (ab COW nahi), toh aage ke writes fault nahi karte.
Kya shared pages sirf read karne wali process kabhi copy trigger karti hai? Nahi — read-only pages par reads allowed hain, toh koi fault aur koi copy nahi hoti.
fork() system call — COW ka primary user.
Page tables and PTE flags — read-only / COW bits yahan rehte hain.
Page faults — woh trap jo copy trigger karta hai.
Virtual memory — COW ek virtual-memory optimization hai.
Demand paging — sibling "lazy" technique (access par load vs write par copy).
mmap and MAP_PRIVATE — file-backed COW.
Reference counting — yeh jaanne ke liye use hota hai ki sharing kab khatam hoti hai.
Snapshots in filesystems (ZFS/Btrfs) — block level par COW.
Single physical copy read-only
Fault handler copies page
Per-frame reference count
fork child shares parent space