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

Класс counting_semaphore

Класс counting_semaphore представляет собой счётный семафор - примитив синхронизации из библиотеки thread. Семафор хранит внутренний счётчик, который уменьшается при захвате и увеличивается при освобождении. Если счётчик равен нулю, поток, пытающийся захватить семафор, блокируется до тех пор, пока другой поток не освободит ресурс. В конструктор мы передаём начальное значение счётчика - максимальное количество потоков, которые могут одновременно получить доступ к ресурсу.

Класс является шаблонным и принимает вторым параметром максимальное значение счётчика, которое по умолчанию равно наибольшему значению типа ptrdiff_t. Основные методы: acquire уменьшает счётчик и блокирует поток, если счётчик равен нулю, try_acquire пытается уменьшить счётчик без блокировки, try_acquire_for и try_acquire_until делают то же самое с ограничением по времени, а release увеличивает счётчик и будит ожидающие потоки.

Синтаксис

#include <semaphore> std::counting_semaphore<MaxValue> sem(initial_value); sem.acquire(); sem.try_acquire(); sem.try_acquire_for(duration); sem.try_acquire_until(time_point); sem.release(update = 1);

Пример

Давайте создадим семафор со счётчиком 2 и запустим 4 потока. Одновременно выполняться будут только 2 потока:

#include <iostream> #include <thread> #include <semaphore> #include <vector> using namespace std; counting_semaphore<2> sem(2); void worker(int id) { sem.acquire(); cout << "Thread " << id << " acquired" << endl; this_thread::sleep_for(chrono::milliseconds(100)); cout << "Thread " << id << " released" << endl; sem.release(); } int main() { vector<thread> threads; for (int i = 1; i <= 4; i++) { threads.push_back(thread(worker, i)); } for (auto& t : threads) { t.join(); } return 0; }

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

"Thread 1 acquired" "Thread 2 acquired" "Thread 1 released" "Thread 2 released" "Thread 3 acquired" "Thread 4 acquired" "Thread 3 released" "Thread 4 released"

Пример

Давайте используем метод try_acquire, который не блокирует поток, а возвращает true или false в зависимости от того, удалось ли захватить семафор:

#include <iostream> #include <semaphore> using namespace std; int main() { counting_semaphore<1> sem(1); if (sem.try_acquire()) { cout << "Acquired" << endl; } if (sem.try_acquire()) { cout << "Acquired again" << endl; } else { cout << "Cannot acquire" << endl; } sem.release(); if (sem.try_acquire()) { cout << "Acquired after release" << endl; } return 0; }

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

"Acquired" "Cannot acquire" "Acquired after release"

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

  • класс thread,
    который представляет поток выполнения
  • класс latch,
    который представляет защёлку - примитив синхронизации
  • класс barrier,
    который представляет барьер - примитив синхронизации
  • метод join,
    который ожидает завершения потока
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить