Concurrency
Multithreading
Computer Science
Programming
Parallel Computing

What is the difference between a thread and a fiber?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Understanding Threads and Fibers

In concurrent programming, the terms "threads" and "fibers" are often discussed in relation to multitasking and process management. Both threads and fibers are units of execution within a program, but they differ in their implementation, scheduling, and use cases. Understanding these differences is crucial for software engineers to choose the optimal concurrency model for their applications.

Threads

Threads are a fundamental concept in operating systems that provide a way to run multiple sequences of operations simultaneously within the same process. Here are some key attributes and examples of threads:

Key Characteristics

  1. Operating System Managed: Threads are managed by the operating system's kernel. The OS schedules threads using its native kernel scheduler which manages CPU time slices.
  2. Pre-emptive Multitasking: Threads are subject to pre-emptive multitasking, meaning the operating system can interrupt a running thread to give control to another thread. This amends the fairness and responsiveness of multitasking environments.
  3. Concurrent Execution: Threads can simultaneously run on multiple CPU cores in multi-core systems, achieving true parallelism.
  4. Shared Memory: Threads within the same process share the same memory space, allowing them to access shared resources but requiring synchronization mechanisms like mutexes or semaphores to avoid race conditions.

Example

cpp
1#include <iostream>
2#include <thread>
3
4void print_message(const std::string& message) {
5    std::cout << message << std::endl;
6}
7
8int main() {
9    std::thread t1(print_message, "Thread 1: Hello");
10    std::thread t2(print_message, "Thread 2: World");
11
12    t1.join();
13    t2.join();
14    return 0;
15}

In this C++ example, we create two threads that print messages concurrently. The std::thread library is leveraged to create and manage threads.

Fibers

Fibers, on the other hand, are lightweight units of execution that are managed at the application level rather than by the operating system.

Key Characteristics

  1. User Space Managed: Fibers are managed entirely in user space. They require explicit scheduling by the programmer or the application framework.
  2. Cooperative Multitasking: Fibers use cooperative multitasking. Each fiber runs until it yields control back to the scheduler, facilitating easier resource management but placing more responsibility on the developer.
  3. Single Thread Execution: Fibers operate within a single thread's context, meaning they can not exceed the concurrent execution limits of their host thread and offer concurrency, not parallelism.
  4. Shared Execution Context: Since fibers are part of the same application thread, they share the same execution context and stack size, reducing overhead but also limiting the use of blocking operations without affecting other fibers.

Example

cpp
1#include <iostream>
2#include <ucontext.h>
3
4constexpr size_t stack_size = 8192;
5
6void fiber_function(ucontext_t* main_context) {
7    std::cout << "Executing fiber!" << std::endl;
8    setcontext(main_context);
9}
10
11int main() {
12    char stack[stack_size];
13    ucontext_t main_context, fiber_context;
14
15    getcontext(&fiber_context);
16    fiber_context.uc_link = &main_context;
17    fiber_context.uc_stack.ss_sp = stack;
18    fiber_context.uc_stack.ss_size = sizeof(stack);
19    makecontext(&fiber_context, (void (*)())fiber_function, 1, &main_context);
20
21    // Swap to the fiber's context
22    swapcontext(&main_context, &fiber_context);
23    
24    std::cout << "Back to main context." << std::endl;
25    return 0;
26}

This C++ example demonstrates a simple fiber that switches control back to the main context after printing a message. The ucontext.h library, part of POSIX, provides the necessary functions for fiber management.

Comparison Table

Below is a table summarizing the key differences between threads and fibers:

AttributeThreadsFibers
ManagementOperating System (Kernel)User Space
MultitaskingPre-emptiveCooperative
ParallelismTrue parallelism (multi-core)Limited to concurrency, not parallelism
SchedulingManaged by the OSApplication-level, manual scheduling
Memory SharingShared across threads in the same processShared within the hosting thread of execution
Context Switching CostHigher (kernel-level switching)Lower (user-level switching)
Best Use CaseSuitable for CPU-bound tasksBest for IO-bound tasks or stateful applications

Additional Considerations

  • Synchronization: Threads typically require synchronization mechanisms due to shared data access, while fibers may entail simpler synchronization if designed properly, as they run cooperatively and less concurrently.
  • Portability: Threads are widely supported across various operating systems and platforms. Fiber support, however, can be more limited depending on the development environment.
  • Ease of Use: While fibers can provide more granular control over execution and state management, they require correct manual scheduling, making them potentially more complex to implement correctly.

By understanding the distinctions between threads and fibers, developers can make informed decisions on appropriate concurrency models for their applications. Whether optimizing for performance, simplicity, or control, recognizing the pros and cons of each approach is invaluable.


Course illustration
Course illustration

All Rights Reserved.