Threads vs. Processes
- Threads share address space, file descriptors, and other resources within a process.
- Processes have independent memory and resources.
- Threads are lighter weight to create and tear down, and inter‐thread communication (shared variables, condition variables) is faster than inter‐process IPC.
- Both processes and threads inherit the signal disposition and mask upon creation; however, while each thread has its own mask, all threads in a process share the same signal disposition.
Thread Mapping
Modern systems expose multiple layers between the bare CPU and your application’s threads:
- Physical Core (Hardware Core): The actual silicon processing unit on the CPU die.
- SMT (Simultaneous Multithreading): Also called “hyper-threads”—each physical core may run 2 (or more) hardware threads, improving utilization.
- Logical Core (OS-visible CPU): The operating system schedules on these SMT contexts as if they were independent CPUs.
- Kernel Thread: An OS-managed schedulable entity bound to a logical core. It has its own kernel stack and context.
- User Thread: The threads your application creates (e.g. via pthreads). These may be mapped onto kernel threads in different ways:
- 1:1 (One-to-One): Each user thread corresponds to a distinct kernel thread. (e.g. Linux pthreads)
- M:1 (Many-to-One): All user threads are scheduled in user space onto a single kernel thread. (e.g. early Solaris “green threads”)
- M:N (Many-to-Many, M >= N): Multiple user threads are multiplexed onto multiple kernel threads. Allows user-space scheduling policies plus true parallelism. (e.g. older FreeBSD, Windows fibers with a scheduler)
Pthreads (POSIX Threads)
Include the header: #include <pthread.h>
1. Creating & Exiting
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine)(void *),
void *arg);
thread
: where the new thread ID is stored
attr
: thread attributes (use NULL for defaults)
start_routine
: void* func(void*)
to run in thread
arg
: argument to pass in