Copy-on-Write Idiom
Saw on this roadmap https://roadmap.sh/cpp
Apparently, the kernel also does a copy-on-write idiom:
3) Round 3: Low-level: fork + printf/flush
These are classic “OS internals” landmines. Here’s the mental model you want ready.
How fork() works (what to say)
fork()creates a new process that is (almost) a duplicate of the parent.- The kernel creates a new process/task structure (PID, registers, file descriptor table refs, etc.).
- Memory is not literally copied immediately: it’s copy-on-write (COW):
- parent and child initially share the same physical pages
- pages are marked read-only
- on write, a page fault triggers a private copy for the writer
- Return values:
- parent gets child PID
- child gets 0
- on failure, returns -1 in parent
Extra credit:
- open file descriptors are copied as references (shared open-file description), so they share file offsets unless you
dupseparately. exec()replaces the child’s address space with a new program (common pattern:fork()thenexec()).
Everyone has a single shared copy of the same data until it’s written, and then a copy is made.
Example (taken from roadmap):
#include <iostream>
#include <memory>
class MyString {
public:
MyString(const std::string &str) : data(std::make_shared<std::string>(str)) {}
// Use the same shared data for copying.
MyString(const MyString &other) : data(other.data) {
std::cout << "Copied using the Copy-Write idiom." << std::endl;
}
// Make a copy only if we want to modify the data.
void write(const std::string &str) {
// Check if there's more than one reference.
if (data.use_count() > 1) {
data = std::make_shared<std::string>(*data);
std::cout << "Copy is actually made for writing." << std::endl;
}
*data = str;
}
private:
std::shared_ptr<std::string> data;
};
int main() {
MyString str1("Hello");
MyString str2 = str1; // No copy operation, just shared references.
str1.write("Hello, World!"); // This is where the actual duplication happens.
return 0;
}Pretty cool!