РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
797 of 815 menu

Функция call_once

Функция call_once гарантирует, что переданная ей функция будет вызвана ровно один раз, даже если несколько потоков попытаются вызвать её одновременно. Это особенно полезно для ленивой инициализации объектов или выполнения однократных настроек в многопоточной среде. В первый параметр мы передаем объект типа once_flag, который хранит состояние вызова, а во второй - вызываемую функцию (или лямбду, или функтор). Дополнительные аргументы можно передать после второго параметра - они будут переданы в вызываемую функцию.

Потоки, которые вызывают call_once с одним и тем же объектом once_flag, будут заблокированы до тех пор, пока первый поток не завершит выполнение переданной функции. Если функция завершится с исключением, то блокировка снимается, и следующий поток попытается выполнить функцию снова.

Синтаксис

#include <mutex> void call_once(once_flag& flag, Callable&& func, Args&&... args);

Пример

Давайте рассмотрим простой пример, где несколько потоков пытаются инициализировать общий ресурс только один раз:

#include <iostream> #include <mutex> #include <thread> using namespace std; once_flag flag; int shared_value = 0; void init() { shared_value = 42; cout << "Initialized: " << shared_value << endl; } void worker() { call_once(flag, init); cout << "Worker sees: " << shared_value << endl; } int main() { thread t1(worker); thread t2(worker); thread t3(worker); t1.join(); t2.join(); t3.join(); return 0; }

Результат выполнения кода:

"Initialized: 42" "Worker sees: 42" "Worker sees: 42" "Worker sees: 42"

Пример

Давайте передадим дополнительные аргументы в функцию через call_once:

#include <iostream> #include <mutex> #include <thread> using namespace std; once_flag flag; void setup(int a, int b) { cout << "Setup: " << a + b << endl; } void worker() { call_once(flag, setup, 10, 20); } int main() { thread t1(worker); thread t2(worker); t1.join(); t2.join(); return 0; }

Результат выполнения кода:

"Setup: 30"

Смотрите также

  • класс once_flag,
    который хранит состояние однократного вызова
  • класс mutex,
    который обеспечивает базовую блокировку
  • класс lock_guard,
    который автоматически управляет блокировкой
  • класс unique_lock,
    который предоставляет гибкое управление блокировкой
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить