Thread
-
A thread is the smallest unit of execution within a process.
-
Multiple threads can exist within the same process and share the same memory space.
TID
-
Thread ID.
PID
-
Process ID.
How many threads can I have per core?
-
A thread is a unit of execution, a core is a physical CPU processing unit.
-
OS defines the relationship by scheduling threads on cores.
-
Creation Limit :
-
Number of threads you can spawn.
-
There is no fixed limit on how many threads you can create per core; you can spawn hundreds or thousands.
-
This can be hundreds to millions, but most will be idle or waiting.
-
Often limited by OS, memory, and thread stack size.
-
Linux:
-
Depends on
ulimit -u, memory, stack size (e.g., ~30Kβ100K).
-
-
Windows:
-
Limited by memory (e.g., ~2Kβ10K threads).
-
-
JVM:
-
Each Java thread uses ~1MB stack by default.
-
-
Go:
-
Goroutines scale to millions (they are not OS threads).
-
-
-
-
Execution Limit :
-
Number of threads that can run at the same time on a core.
-
Only a limited number can be executed concurrently per core.
-
Can be 1 or 2 (with SMT/hyper-threading).
-
SMT (Simultaneous Multithreading) :
-
Is a CPU-level technique that allows a single physical core to execute multiple threads simultaneously by sharing its internal execution resources.
-
Hyper-threading :
-
It's a implementation of SMT by Intel.
-
A single core can run two hardware threads, allowing limited parallelism per core.
-
-
-
Example :
-
1 thread, 1 core
-
Thread runs directly on the core.
-
-
N threads, 1 core
-
OS time-slices threads β concurrent, not parallel.
-
-
N threads, M cores
-
Threads are distributed across cores and context-switched as needed.
-
-
N threads, M cores
-
Potential parallel execution, if the OS schedules them simultaneously.
-
-
-
-
Affinity :
-
Threads can be pinned to specific cores to improve cache locality and reduce context switching.
-
-
Load balancing :
-
OS may migrate threads between cores to balance CPU load.
-
Thread-Safety
-
Code is thread-safe if it behaves correctly when accessed concurrently by multiple threads.
-
No race conditions.
-
No data corruption.
-
No undefined behavior.
-
-
Expected output is always produced, regardless of timing.
-
Code is thread-safe if it functions correctly when executed concurrently by multiple threads.
-
Immutability :
-
Immutable objects cannot be changed, inherently thread-safe.
-
-
Thread-Local Storage :
-
Store separate variable copies for each thread.
-
Example :
thread_localin C++,ThreadLocal<T>in Java,threading.local()in Python.
-
-
Lock-Free or Wait-Free Algorithms :
-
Data structures avoiding locks but preventing race conditions.
-
Advanced : Requires atomic operations and memory ordering.
-
-
Avoid Shared State :
-
Design so threads do not share mutable data; use message-passing or immutable queues.
-
Example : Actor model (Erlang, Akka in Scala).
-
Fibers
-
Fiber: lightweight thread , manually scheduled, cooperatively multitasked.
-
Not OS-managed; must explicitly yield control.
-
Create, switch, resume fibers manually.
-
Hard to use correctly; OS doesn't schedule them.
-
-
Optimize task switching within a single thread.
-
Each fiber has its own stack.
-
More like user-space threads, no preemption.
-
Use Case :
-
User-level schedulers
-
High-performance I/O systems
-
Green thread implementations
-
-
Exemples :
-
Found in lower-level systems like Windows fibers, libfiber, or languages like Ruby , C++ , and Rust .
-
-
[cppcon 2017] "Not currently in C++. Available via Boost.Fiber"
Green Thread
-
A thread that is scheduled by a runtime library instead of natively by the underlying OS.
-
Used to emulate multithreading without OS support.
-
[cppcon 2017] "Not currently in C++. Most OSs support native threads".
-
Not widely used outside of:
-
Go.
-
Erland.
-
Sort of.
-
-
Java.
-
In older versions.
-
-
Goroutine
-
Lightweight user-space thread , managed by Go runtime, not OS.
-
Created with
gokeyword:go myFunction -
Multiplexed onto fewer OS threads by Go scheduler.
Comparisons
-
OS Threads
-
Goroutines are cheaper: Go can run thousands of goroutines on a few OS threads.
-
Less control: You donβt pin goroutines to cores or manage priorities.
-
Automatic scheduling: Goβs scheduler handles context switching without OS involvement.
-
-
Fibers/Coroutines
-
Goroutines are preemptively scheduled , unlike pure coroutines which require manual yielding.
-
More natural for writing blocking-style code that looks synchronous.
-
-
Green Threads
-
Goroutines are a modern green-thread model but include runtime preemption and parallelism support on multiple cores.
-
Advantages
-
Simple syntax:
go func() -
Low memory and CPU overhead.
-
Built-in channels provide CSP-style synchronization.
-
Easier to write concurrent code with synchronous semantics.
Disadvantages
-
Less control than OS threads .
-
Go runtime scheduling overhead may become a bottleneck in specific low-latency or real-time workloads.
-
Blocking syscalls (C FFI) can still tie up OS threads unless handled specially.