Threading Basics

Back

Loading concept...

🧡 C++ Threading Basics: The Kitchen Story

Imagine you’re the head chef in a busy restaurant. You have ONE kitchen, but MANY dishes to prepare. What if you could have multiple cooks working at the same time?


🍳 What is a Thread?

Think of your program as a restaurant kitchen.

  • The kitchen = your computer’s CPU
  • The head chef = your main program
  • Helper cooks = threads!

Without threads, the head chef does EVERYTHING alone. With threads, multiple cooks work at the same time!

#include <thread>
#include <iostream>

// This is like a cook's recipe
void cookPasta() {
    std::cout << "Cooking pasta...\n";
}

int main() {
    // Hire a helper cook!
    std::thread helper(cookPasta);
    helper.join();
    return 0;
}

πŸš€ Creating Threads

The Simple Truth: Creating a thread is like hiring a new cook and giving them a recipe to follow.

Method 1: Using a Function

#include <thread>
#include <iostream>

void sayHello() {
    std::cout << "Hello from thread!\n";
}

int main() {
    std::thread t(sayHello);
    t.join();
    return 0;
}

Method 2: Using a Lambda

#include <thread>
#include <iostream>

int main() {
    std::thread t([]() {
        std::cout << "Hello from lambda!\n";
    });
    t.join();
    return 0;
}

πŸ’‘ Key Points

What Meaning
std::thread t(func) Hire cook, give recipe
t.join() Wait for cook to finish
t.detach() Let cook work alone

🀝 Joining Threads

Story Time: Imagine the head chef needs the pasta BEFORE serving. They must WAIT for the helper to finish.

void cookPasta() {
    // Takes 5 seconds
    std::this_thread::sleep_for(
        std::chrono::seconds(2));
    std::cout << "Pasta ready!\n";
}

int main() {
    std::thread pasta(cookPasta);

    std::cout << "Waiting for pasta...\n";
    pasta.join(); // WAIT here!

    std::cout << "Now I can serve!\n";
    return 0;
}

What Happens?

graph TD A["Main starts"] --> B["Create pasta thread"] B --> C["Main waits at join"] B --> D["Pasta cooks..."] D --> E["Pasta done!"] E --> F["Main continues"] C --> F

⚠️ Rule #1

ALWAYS join or detach a thread before it goes out of scope!

If you forget, your program CRASHES! πŸ’₯


πŸ¦… Detaching Threads

Different Story: Sometimes the helper cook makes bread for tomorrow. You don’t need to wait!

void bakeBread() {
    std::this_thread::sleep_for(
        std::chrono::hours(2));
    std::cout << "Bread ready!\n";
}

int main() {
    std::thread bread(bakeBread);
    bread.detach(); // Go work alone!

    // Main continues immediately
    std::cout << "I'm not waiting!\n";
    return 0;
}

Join vs Detach

Join 🀝 Detach πŸ¦…
Wait for thread Don’t wait
Know when done Don’t know
Safe & controlled Runs freely
Like waiting for pizza Like ordering delivery

⚠️ Warning!

Once detached, you LOSE control. The thread runs until:

  • It finishes naturally, OR
  • The program ends

πŸ“¦ Thread Arguments

The Fun Part: What if the cook needs ingredients? Pass them as arguments!

Passing Simple Values

void greet(std::string name) {
    std::cout << "Hello, " << name << "!\n";
}

int main() {
    std::thread t(greet, "Alice");
    t.join();
    return 0;
}

Passing Multiple Arguments

void cook(std::string dish, int mins) {
    std::cout << "Cooking " << dish
              << " for " << mins << " mins\n";
}

int main() {
    std::thread t(cook, "Pizza", 15);
    t.join();
    return 0;
}

🎯 Passing by Reference

Tricky Part: Threads COPY arguments by default!

void addOne(int& num) {
    num = num + 1;
}

int main() {
    int x = 5;

    // WRONG - x won't change!
    // std::thread t(addOne, x);

    // RIGHT - use std::ref()
    std::thread t(addOne, std::ref(x));
    t.join();

    std::cout << x << "\n"; // Prints 6!
    return 0;
}

πŸ“‹ Argument Rules

Want to… Use this
Pass a copy Just pass it
Pass a reference Use std::ref(var)
Pass a pointer Just pass it

πŸŽͺ The Complete Picture

graph TD A["Main Thread"] --> B{Create Thread} B --> C["Thread runs function"] B --> D{Choose action} D --> E["join - Wait"] D --> F["detach - Let go"] E --> G["Thread done"] G --> H["Main continues"] F --> I["Main continues immediately"] C --> J["Thread finishes eventually"]

πŸ† Quick Summary

Creating Threads

std::thread t(function);      // Basic
std::thread t(func, arg1);    // With args
std::thread t([](){/*...*/}); // Lambda

Managing Threads

t.join();   // Wait for it
t.detach(); // Let it go
t.joinable(); // Can I join/detach?

Passing Arguments

std::thread t(func, value);     // Copy
std::thread t(func, std::ref(x)); // Reference

🎭 Remember the Kitchen!

Concept Kitchen Analogy
Thread Helper cook
join() Wait for dish
detach() Work independently
Arguments Ingredients
Main thread Head chef

🌟 You Did It!

You now understand:

  • βœ… How to create threads
  • βœ… When to join (wait)
  • βœ… When to detach (let go)
  • βœ… How to pass data to threads

Next adventure: Protecting your kitchen from chaos with mutexes! πŸ”

Happy threading! 🧡

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.