Какие знаешь примитивы синхронизации
1️⃣ Как кратко ответить
Примитивы синхронизации в C++ включают мьютексы (std::mutex), рекурсивные мьютексы (std::recursive_mutex), условные переменные (std::condition_variable), барьеры, атомарные операции (std::atomic), семафоры и спинлоки. Они используются для управления доступом к общим ресурсам в многопоточных приложениях.
2️⃣ Подробное объяснение темы
Примитивы синхронизации — это механизмы, которые позволяют управлять доступом к общим ресурсам в многопоточных приложениях, предотвращая состояние гонки и обеспечивая корректное выполнение программы. Рассмотрим основные примитивы синхронизации в C++.
Мьютексы (std::mutex)
Мьютекс (от англ. "mutual exclusion" — взаимное исключение) — это объект, который позволяет ограничить доступ к ресурсу так, чтобы в каждый момент времени только один поток мог его использовать.
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx; // Создаем мьютекс
void print_message(const std::string& message) {
mtx.lock(); // Захватываем мьютекс
std::cout << message << std::endl; // Печатаем сообщение
mtx.unlock(); // Освобождаем мьютекс
}
int main() {
std::thread t1(print_message, "Hello from thread 1");
std::thread t2(print_message, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
std::mutex mtx;— объявление мьютекса.mtx.lock();— захват мьютекса, блокировка доступа к ресурсу.mtx.unlock();— освобождение мьютекса, разблокировка доступа.
Рекурсивные мьютексы (std::recursive_mutex)
Рекурсивный мьютекс позволяет одному и тому же потоку захватывать мьютекс несколько раз без блокировки. Это полезно, если функция вызывает саму себя и требует синхронизации.
#include <iostream>
#include <thread>
#include <mutex>
std::recursive_mutex rec_mtx;
void recursive_function(int count) {
if (count <= 0) return;
rec_mtx.lock();
std::cout << "Count: " << count << std::endl;
recursive_function(count - 1);
rec_mtx.unlock();
}
int main() {
std::thread t1(recursive_function, 5);
t1.join();
return 0;
}
std::recursive_mutex rec_mtx;— объявление рекурсивного мьютекса.- Позволяет одному потоку захватывать мьютекс несколько раз.
Условные переменные (std::condition_variable)
Условные переменные используются для блокировки потока до тех пор, пока не будет выполнено определенное условие.
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void wait_for_ready() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return ready; });
std::cout << "Thread is ready!" << std::endl;
}
void set_ready() {
std::lock_guard<std::mutex> lock(mtx);
ready = true;
cv.notify_one();
}
int main() {
std::thread t1(wait_for_ready);
std::thread t2(set_ready);
t1.join();
t2.join();
return 0;
}
std::condition_variable cv;— объявление условной переменной.cv.wait(lock, [] { return ready; });— блокировка потока до выполнения условия.cv.notify_one();— уведомление одного потока о выполнении условия.
Атомарные операции (std::atomic)
Атомарные операции позволяют выполнять операции над переменными без использования мьютексов, обеспечивая безопасность потоков.
#include <iostream>
#include <thread>
#include <atomic>
std::atomic<int> counter(0);
void increment() {
for (int i = 0; i < 1000; ++i) {
++counter;
}
}
int main() {
std::thread t1(increment);
std::thread t2(increment);
t1.join();
t2.join();
std::cout << "Counter: " << counter << std::endl;
return 0;
}
std::atomic<int> counter(0);— объявление атомарной переменной.++counter;— атомарное увеличение переменной.
Семафоры
Семафоры управляют доступом к ресурсу, позволяя ограниченному числу потоков использовать его одновременно.
Спинлоки
Спинлоки — это примитивы, которые активно ожидают освобождения ресурса, постоянно проверяя его состояние. Они могут быть полезны в системах с низкой задержкой, но могут привести к избыточному использованию процессора.
Эти примитивы синхронизации помогают разработчикам создавать безопасные и эффективные многопоточные приложения, управляя доступом к общим ресурсам и предотвращая состояние гонки.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться