Thread Creation and Synchronization in C++

Thread Creation and Synchronization in C++

In the C++ programming language, creating threads, properly managing thread synchronization, and maintaining thread-safety are important concepts or features for creating a robust C++ program. Creating threads in a C++ program allows C++ users to perform multiple tasks simultaneously. Thread synchronization features help you determine how threads interact with shared resources in an existing program, providing better user interaction with control and predictability.

Thread Creation and Synchronization in C++

Creating Threads in C++ Programming.

In any C++ program, the std::thread class (launched in C++11 version) is used to create threads and manage thread management.

Creating a Basic Thread in C++ Programming.

To create a basic thread in a C++ program, C++ users instantiate a std::thread object and pass a user-defined class function (or callable object, such as a lambda function expression) to be executed through that thread. If needed, C++ users can also pass custom function parameter values ​​as arguments to the thread being called in the current program.

Example of creating a basic thread in a C++ program.

#include <iostream>

#include <thread>

void BasicThread() {

std::cout << “Vcanhelpsu create with a new thread” << std::endl;

}

int main() {

// Here we create and launch a new thread

std::thread t(BasicThread);

// Here we wait for the thread to finish

t.join(); // Here it blocks the main thread until t finishes

return 0;

}

Explanation of creating a basic thread in a C++ program.

  • In this example, std::thread t(BasicThread); creates a new thread that will run a BasicThread function in the current program.
  • In this, the t.join(); function ensures that the main thread waits for t to terminate before proceeding.

Passing Arguments to Threads in C++ Programming.

In C++ programs, you can pass arguments to user-defined functions that run in user-defined threads. Here, you simply use them by passing the name of the function followed by the std::thread constructor.

Example of passing arguments to a C++ thread.

#include <iostream>

#include <thread>

void countTotal(int p, int q) {

std::cout << “The total of p and q is – ” << p + q << std::endl;

}

int main() {

int m = 3;

int n = 8;

// Here we pass arguments to the thread function

std::thread t(countTotal, m, n);

// Here we wait for the thread to finish

t.join();

return 0;

}

Explanation of passing arguments to a C++ thread.

  • In this example, std::thread t(countTotal, m, n); creates a thread that runs the countTotal thread function with m and n arguments.

Using lambda functions with threads in C++ programming.

Instead of creating a separate function in a C++ program, C++ users can use a user-defined custom lambda function directly with a thread. Lambda functions are particularly used when C++ users want to create small tasks that do not need to be reused throughout the program.

Example of a lambda function with a thread in C++.

#include <iostream>

#include <thread>

int main() {

int p = 6;

int q = 3;

// Here we create and launch a thread using a lambda function method

std::thread t([p, q]() {

std::cout << “The total of p and q is – ” << p + q << std::endl;

});

// Here we wait for the thread to finish first

t.join();

return 0;

}

Explanation of a lambda function with a thread in C++.

  • In this example, the lambda expression [p, q]() { … } is passed to the std::thread, and it captures the values ​​of p and q by value from the surrounding scope.

Joining and Detaching Threads in C++ Programming.

After creating a new thread in C++ programming, the C++ user must either join it or dispatch it.

Joining and Detaching Threads in C++ Programming.

  • join() – This blocks the calling thread (usually the main thread) in a C++ program until the thread being joined in the current program has finished executing. One way to verify thread joining in a program is to wait for the newly created thread to complete before the main thread can proceed.
  • detach() – This allows a user-defined thread in a C++ program to run independently, without the main thread waiting for it. After detaching a required thread from the current program, it becomes a “detached” thread and cannot be joined by the C++ user.

Example of thread joining in a C++ program.

#include <iostream>

#include <thread>

void previewInfo() {

std::cout << “System define Thread is executed.” << std::endl;

}

int main() {

std::thread t(previewInfo);

// Here we wait for the thread to finish first

t.join(); // Here the main thread will wait for t to finish and then move next

return 0;

}

Explanation of thread joining in a C++ program.

  • In this example, t.join() ensures that the main thread waits for t to terminate execution.

Example of thread detach in a C++ program.

#include <iostream>

#include <thread>

#include <chrono>

void testThread() {

std::this_thread::sleep_for(std::chrono::seconds(2));

std::cout << “Here Thread delayed for 2 second.” << std::endl;

}

int main() {

std::thread t(testThread);

// here we detach the thread, main thread don’t wait for it process

t.detach();

//here main thread continues execution

std::cout << “Main thread is ready to continue.” << std::endl;

std::this_thread::sleep_for(std::chrono::seconds(3)); // here it gives detached thread time to finish first

return 0;

}

Explanation of thread detach in a C++ program.

  • In this example, t.detach() allows a thread to run independently. The main thread doesn’t wait for it to terminate, but instead allows the program enough time to complete the detached thread’s execution.
  • Remember, be careful when using the detach() function method in a C++ program, as once it is detached from a thread, it cannot be reattached or synchronized. If the main thread terminates and exits before the detached thread, it may result in undefined thread behavior if the detached thread attempts to access resources that have already been destroyed.

Thread Synchronization in C++ Programming

When multiple threads in a C++ program access a shared resource, C++ users must ensure proper thread synchronization to avoid race conditions and data corruption. C++ provides users with several mechanisms to synchronize threads, such as mutexes, locks, and condition variables.

Mutex (std::mutex)

A mutex (a shortened version of mutual exclusion) is used in C++ programs to prevent multiple threads from simultaneously accessing shared data. You lock the mutex before accessing the shared resource in a thread, and unlock it when the task is complete.

Example of using a mutex for synchronization in C++.

#include <iostream>

#include <thread>

#include <mutex>

std::mutex mtx; // here we define mutex to protect shared thread data

void displayThread(int data) {

std::lock_guard<std::mutex> lock(mtx); //here we lock the mutex automatically

std::cout << “Thread ” << data << ” is displaying information.” << std::endl;

}

int main() {

std::thread td1(displayThread, 1);

std::thread td2(displayThread, 2);

// here we wait for both threads to finish first

td1.join();

td2.join();

return 0;

}

Explanation of using a mutex for synchronization in C++.

  • In this example, std::lock_guard<std::mutex> lock(mtx); ensures that the mutex in mtx is automatically locked when the current thread enters its scope, and automatically released when it exits its scope (e.g., when the lock object goes out of its scope).
  • This feature prevents multiple threads from simultaneously printing output to std::cout, which could cause interleaved or garbled output in the current program.

std::unique_lock vs. std::lock_guard in C++.

  • std::lock_guard – This is a simple, RAII-style lock in C++ thread programs. It locks the mutex when it is created and automatically releases it when it goes out of scope.
  • std::unique_lock – A more flexible method than std::lock_guard in C++ thread programs. It provides features for manual thread object locking and unlocking, and can be implemented with condition variables or (for more advanced uses) within threads.

Leave a Reply