c++ synchronization primitives example programs
Sure! Here are some examples of synchronization primitives in C++ along with explanations for each step:
Example 1: Mutex
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void printMessage(const std::string& message) {
std::lock_guard<std::mutex> lock(mtx);
std::cout << message << std::endl;
}
int main() {
std::thread t1(printMessage, "Hello");
std::thread t2(printMessage, "World");
t1.join();
t2.join();
return 0;
}
Explanation:
1. We include the necessary headers for using mutex, threads, and IO operations.
2. We declare a global mutex variable mtx
.
3. We define a function printMessage
that takes a string message as an argument and prints it.
4. Inside the printMessage
function, we create a lock_guard
object lock
which locks the mutex mtx
as soon as it is constructed.
5. The message is then printed to the console.
6. In the main
function, we create two threads t1
and t2
, which call the printMessage
function with different messages.
7. We wait for both threads to finish their execution by calling join
on each thread.
8. Finally, the program returns 0.
Example 2: Semaphore
#include <iostream>
#include <thread>
#include <semaphore.h>
sem_t sem;
void printMessage(const std::string& message) {
sem_wait(&sem);
std::cout << message << std::endl;
sem_post(&sem);
}
int main() {
sem_init(&sem, 0, 1);
std::thread t1(printMessage, "Hello");
std::thread t2(printMessage, "World");
t1.join();
t2.join();
sem_destroy(&sem);
return 0;
}
Explanation:
1. We include the necessary headers for using semaphores, threads, and IO operations.
2. We declare a semaphore variable sem
.
3. We define a function printMessage
that takes a string message as an argument and prints it.
4. Inside the printMessage
function, we call sem_wait
to decrement the semaphore value by 1, effectively acquiring the semaphore.
5. The message is then printed to the console.
6. After printing the message, we call sem_post
to increment the semaphore value by 1, releasing the semaphore.
7. In the main
function, we initialize the semaphore sem
with an initial value of 1.
8. We create two threads t1
and t2
, which call the printMessage
function with different messages.
9. We wait for both threads to finish their execution by calling join
on each thread.
10. Finally, we destroy the semaphore using sem_destroy
.
11. The program returns 0.
These examples demonstrate the use of two common synchronization primitives in C++, mutex and semaphore, to ensure thread-safe access to shared resources. The mutex guarantees that only one thread can execute the critical section of code at a time, while the semaphore allows a specified number of threads to access a shared resource concurrently.