Для чего нужна std::condition_variable
1️⃣ Как кратко ответить
std::condition_variable используется для синхронизации потоков, позволяя одному или нескольким потокам ждать, пока другой поток не уведомит их о наступлении определенного события. Это позволяет эффективно управлять доступом к общим ресурсам и координировать выполнение потоков.
2️⃣ Подробное объяснение темы
std::condition_variable — это механизм синхронизации в C++, который позволяет потокам взаимодействовать друг с другом, ожидая наступления определенных условий. Он используется в многопоточных приложениях для координации работы потоков, особенно когда один поток должен ждать, пока другой поток выполнит определенные действия или изменит состояние программы.
Зачем это нужно
В многопоточных приложениях часто возникает необходимость в том, чтобы один поток ждал, пока другой поток выполнит определенные действия. Например, поток может ждать, пока другой поток не завершит запись данных в общий буфер. Использование std::condition_variable позволяет избежать активного ожидания (busy-waiting), что экономит ресурсы процессора и делает программу более эффективной.
Как это работает
std::condition_variable работает в связке с мьютексами (std::mutex). Поток, который должен ждать, блокирует мьютекс и вызывает метод wait() объекта std::condition_variable. Это освобождает мьютекс и переводит поток в состояние ожидания. Когда другой поток изменяет состояние программы и вызывает метод notify_one() или notify_all(), ожидающий поток пробуждается и может продолжить выполнение.
Пример кода
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx; // Мьютекс для защиты общего ресурса
std::condition_variable cv; // Условная переменная для синхронизации
bool ready = false; // Флаг, указывающий на готовность данных
void worker_thread() {
std::unique_lock<std::mutex> lock(mtx); // Блокируем мьютекс
cv.wait(lock, []{ return ready; }); // Ждем, пока ready не станет true
// После пробуждения продолжаем выполнение
std::cout << "Worker thread is processing data\n";
}
void prepare_data() {
std::this_thread::sleep_for(std::chrono::seconds(1)); // Имитация подготовки данных
{
std::lock_guard<std::mutex> lock(mtx); // Блокируем мьютекс
ready = true; // Устанавливаем флаг готовности
}
cv.notify_one(); // Уведомляем один из ожидающих потоков
}
int main() {
std::thread worker(worker_thread); // Создаем поток-работник
std::thread preparer(prepare_data); // Создаем поток, подготавливающий данные
worker.join(); // Ожидаем завершения потока-работника
preparer.join(); // Ожидаем завершения потока, подготавливающего данные
return 0;
}
Объяснение кода
std::mutex mtx;: Создаем мьютекс для защиты общего ресурса.std::condition_variable cv;: Создаем условную переменную для синхронизации потоков.bool ready = false;: Флаг, указывающий на готовность данных.worker_thread(): Функция, выполняемая в потоке-работнике. Она блокирует мьютекс и ждет, покаreadyне станетtrue.prepare_data(): Функция, имитирующая подготовку данных. После подготовки она устанавливаетreadyвtrueи уведомляет один из ожидающих потоков.main(): Создает и запускает два потока, затем ожидает их завершения.
Этот пример демонстрирует, как std::condition_variable позволяет потоку-работнику ждать, пока данные не будут готовы, и как поток, подготавливающий данные, уведомляет об этом.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться