Назад к вопросам
Middle
175
questionbank
Что такое условная переменная (conditional variable)?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Условная переменная — это примитив синхронизации, используемый для организации взаимодействия между потоками. Она позволяет потоку (или потокам) ждать наступления определенного условия, пока другой поток не уведомит его (их) о выполнении этого условия. Обычно используется совместно с мьютексом для обеспечения атомарности проверки условия и ожидания.
Основные операции:
- wait(mutex): Поток блокируется до тех пор, пока не будет получен сигнал. Перед блокировкой мьютекс атомарно освобождается. После получения сигнала мьютекс атомарно захватывается снова.
- notify_one(): Разблокирует один поток из тех, кто ждет на этой условной переменной.
- notify_all(): Разблокирует все потоки, которые ждут на этой условной переменной.
Проблема ложных пробуждений (spurious wakeups): Поток может быть разбужен, даже если notify_one или notify_all не были вызваны. Поэтому ожидание на условной переменной всегда должно происходить в цикле, проверяющем условие.
Пример на C++ (используя std::condition_variable):
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
std::vector<int> data;
void worker_thread() {
std::unique_lock<std::mutex> lock(mtx);
// Ждем, пока условие не станет истинным
cv.wait(lock, []{ return ready; });
// Условие выполнено, работаем с данными
std::cout << "Worker thread processing data: ";
for (int d : data) {
std::cout << d << " ";
}
std::cout << std::endl;
// lock автоматически освобождается при выходе из функции
}
int main() {
std::thread worker(worker_thread);
// Подготавливаем данные
{
std::lock_guard<std::mutex> lock(mtx);
data = {1, 2, 3, 4, 5};
ready = true; // Устанавливаем условие
} // lock_guard освобождает мьютекс
// Уведомляем ожидающий поток
cv.notify_one();
worker.join();
return 0;
}