Crisp answer: A process is an isolated program with its own memory space. Threads are units of execution within a process that share the same memory space and file descriptors.
Process:
A process is a running instance of a program. It has:
- Its own virtual address space (memory is not shared with other processes without explicit IPC)
- Its own file descriptor table
- Its own PID
- Independent resource accounting (CPU, memory limits)
- Communication via IPC: pipes, sockets, shared memory, signals
Creating a process is expensive because the OS must copy or clone the entire
virtual address space (fork()).
Thread:
A thread is a unit of execution within a process. Multiple threads in the same process share:
- The same virtual address space (all memory is shared)
- The same file descriptors
- The same PID (they have unique TIDs — thread IDs)
Creating a thread is cheap because no address space copying is needed.
In Linux, threads are implemented via clone():
Linux doesn't have a separate "thread" concept at the kernel level. Threads
are created with the clone() syscall with flags that specify what to share:
CLONE_VM (share memory), CLONE_FILES (share file descriptors), etc. The
fork() syscall is actually clone() without those sharing flags.
This means in Linux, from the kernel's perspective, threads look like
lightweight processes with shared resources. ps aux shows all threads;
ps -eLf shows threads separately.
ps -eLf | grep <process> # See threads — LWP column is thread ID
cat /proc/<pid>/status # Threads: N shows thread count
ls /proc/<pid>/task/ # One directory per thread
pstree -p <pid> # Tree view showing threads
Race conditions and synchronisation:
Because threads share memory, concurrent access to the same data causes race conditions. Solutions: mutexes, semaphores, channels (Go), locks. The shared memory model is both the power (fast communication) and the danger (bugs) of threads.
Containers and processes:
Containers are processes (or process trees), not VMs. A container is a process isolated using kernel namespaces and cgroups. From the kernel's view, a containerised process is a regular process with a restricted view of the system.
ps aux # Shows container processes alongside host processes
docker inspect --format '{{.State.Pid}}' <container> # Get container's PID on host
What to say in the interview:
"A process has its own isolated memory space, file descriptors, and PID — isolation is the defining property. Threads share all of that within a process, making communication fast but requiring synchronisation to avoid race conditions. In Linux, threads are implemented with the clone() syscall with sharing flags set — the kernel doesn't have a fundamentally different concept, just different sharing modes. From an ops perspective: if you need to isolate workloads, use processes or containers. If you need concurrent work within a program sharing data, use threads."