This question tests whether you can draw the resource boundary precisely. The interviewer wants the kernel structures — not "threads are lighter, processes are heavier."
The mental model: on Linux, a process and a thread are the same unit to the scheduler — a task_struct. The difference is what gets shared. A process is a task_struct with its own mm_struct (page tables), file descriptor table, signal handlers, and PID. A thread is a task_struct whose mm_struct, file tables, and signal handlers are the same objects as other threads in its thread group.
Walk through the mechanism. pthread_create calls clone() with flags like CLONE_VM | CLONE_FS | CLONE_FILES — share the address space, the working directory, and the file descriptor table. fork() calls clone() with those flags unset, so the child gets a new mm_struct and a new file descriptor table (a shallow copy pointing at the same open files). The practical consequences fall out of that sharing:
- Threads see the same heap and globals — they're literally the same virtual pages, so shared state needs no IPC, just synchronization.
- Each thread still gets its own stack and register state, because those are per-
task_struct. - A segfault in one thread kills the whole process, because the address space — including the corrupting thread's stack — is shared.
- Threads can't live without their process; the process object is the anchor.
Scheduling is where the "lightweight" claim is precise: switching between threads of one process only swaps register state, not CR3 and page tables, so TLB entries survive. Creating a thread is also cheaper than fork(): no page tables to copy (though COW makes fork's copy cheap too).
Tradeoffs and edge cases worth naming:
getpid()vsgettid(): all threads report the same PID (tgid); the kernel distinguishes them by TID.fork()in a multithreaded process copies only the calling thread into the child — a classic surprise when the child inherits locked mutexes.- Threads share signal handlers, so one thread's handler runs in whatever thread is unlucky enough to be interrupted.
- Processes get fault isolation and clean crash boundaries; threads get cheap sharing and shared fate.
A strong closing line: a thread is a schedulable unit that shares its process's address space and resources, and everything else — cost, isolation, lifetime — follows from that one sharing decision.