EZ

Eduzan

Learning Hub

Eduzan
Eduzan / C++

Advance Cpp

Computer Science / C++ tutorial chapter - Published 2025-12-13 - C++

Multithreading is a feature in C++ that allows multiple threads to run concurrently, making better use of the CPU. Each thread is a separate flow of execution within a process, which allows multiple parts of a program to run in parallel.

Multithreading support was added in C++11, and before that, programmers had to use the POSIX threads (pthreads) library. C++11 introduced std::thread, which made multithreading much easier and portable across different platforms. The std::thread class and related utilities are provided in the <thread> header.

Syntax for Creating a Thread:

std::thread thread_object(callable);

Here, std::thread represents a single thread in C++. To start a new thread, we create a std::thread object and pass a callable to its constructor. A callable can be:

1. A Function Pointer
2. A Lambda Expression
3. A Function Object (Functor)
4. A Non-Static Member Function
5. A Static Member Function

Once the callable is passed, the thread will execute the corresponding code.

Launching a Thread Using a Function Pointer

A function pointer can be passed to a std::thread constructor to launch a thread:

void my_function(int value)
{
    for (int i = 0; i < value; i++) {
        std::cout << "Thread using function pointer\n";
    }
}

// Creating and launching the thread
std::thread my_thread(my_function, 5);

Launching a Thread Using a Lambda Expression

A lambda expression is a convenient way to define a callable on the fly. Here’s how to use it to launch a thread:

auto my_lambda = [](int value) {
    for (int i = 0; i < value; i++) {
        std::cout << "Thread using lambda expression\n";
    }
};

// Launching a thread using the lambda expression
std::thread my_thread(my_lambda, 5);

Launching a Thread Using a Function Object (Functor)

A function object (functor) is a class with an overloaded () operator. Here’s an example:

class Functor {
public:
    void operator()(int value) {
        for (int i = 0; i < value; i++) {
            std::cout << "Thread using functor\n";
        }
    }
};

// Launching a thread using a function object
std::thread my_thread(Functor(), 5);

Output:

a < b  : 0
a > b  : 1
a <= b: 0
a >= b: 1
a == b: 0
a != b : 1

Launching a Thread Using a Non-Static Member Function

Non-static member functions require an instance of the class to be called. Here’s how to use a non-static member function in a thread:

class MyClass {
public:
    void my_method(int value) {
        for (int i = 0; i < value; i++) {
            std::cout << "Thread using non-static member function\n";
        }
    }
};

// Creating an instance of the class
MyClass my_obj;

// Launching the thread
std::thread my_thread(&MyClass::my_method, &my_obj, 5);

Launching a Thread Using a Static Member Function

Static member functions do not require an instance of the class and can be directly passed to a thread:

class MyClass {
public:
    static void my_static_method(int value) {
        for (int i = 0; i < value; i++) {
            std::cout << "Thread using static member function\n";
        }
    }
};

// Launching the thread using the static member function
std::thread my_thread(&MyClass::my_static_method, 5);

Waiting for Threads to Finish

Once a thread is launched, we may need to wait for it to finish before proceeding. The join() function blocks the calling thread until the specified thread completes execution.

int main() {
    std::thread t1(my_function, 5);
    t1.join();  // Wait for t1 to finish

    // Proceed with other tasks after t1 finishes
}

Complete C++ Program for Multithreading

Below is a complete C++ program that demonstrates launching threads using different callables, including a function pointer, lambda expression, functor, and member functions:

#include <iostream>
#include <thread>

// Function to be used as a function pointer
void function_pointer(int value) {
    for (int i = 0; i < value; i++) {
        std::cout << "Thread using function pointer\n";
    }
}

// Functor (Function Object)
class Functor {
public:
    void operator()(int value) {
        for (int i = 0; i < value; i++) {
            std::cout << "Thread using functor\n";
        }
    }
};

// Class with member functions
class MyClass {
public:
    void non_static_function() {
        std::cout << "Thread using non-static member function\n";
    }
    static void static_function() {
        std::cout << "Thread using static member function\n";
    }
};

int main() {
    std::cout << "Launching threads...\n";

    // Launch thread using function pointer
    std::thread t1(function_pointer, 3);

    // Launch thread using functor
    Functor functor;
    std::thread t2(functor, 3);

    // Launch thread using lambda expression
    auto lambda = [](int value) {
        for (int i = 0; i < value; i++) {
            std::cout << "Thread using lambda expression\n";
        }
    };
    std::thread t3(lambda, 3);

    // Launch thread using non-static member function
    MyClass obj;
    std::thread t4(&MyClass::non_static_function, &obj);

    // Launch thread using static member function
    std::thread t5(&MyClass::static_function);

    // Wait for all threads to finish
    t1.join();
    t2.join();
    t3.join();
    t4.join();
    t5.join();

    std::cout << "All threads finished.\n";

    return 0;
}

Output:

Launching threads...
Thread using function pointer
Thread using function pointer
Thread using function pointer
Thread using lambda expression
Thread using lambda expression
Thread using lambda expression
Thread using functor
Thread using functor
Thread using functor
Thread using non-static member function
Thread using static member function
All threads finished.
End of lesson.