Thread

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_local  in 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 go  keyword: 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.