← Назад ко всем вопросам

Что такое семафоры

1️⃣ Как кратко ответить

Семафоры — это механизмы синхронизации, используемые для управления доступом к общим ресурсам в многопоточных и многопроцессных приложениях. Они позволяют ограничивать количество потоков, которые могут одновременно использовать ресурс, предотвращая состояния гонки и обеспечивая корректное выполнение программы.

2️⃣ Подробное объяснение темы

Семафоры — это один из основных инструментов синхронизации в программировании, особенно в контексте многопоточности и многозадачности. Они помогают управлять доступом к общим ресурсам, таким как память, файлы или устройства, чтобы избежать конфликтов и обеспечить корректное выполнение программы.

Основные концепции

Семафор можно представить как счетчик, который управляет доступом к ресурсу. Существует два основных типа семафоров:

  1. Двоичный семафор (бинарный семафор): работает как простой переключатель с двумя состояниями — занято и свободно. Он аналогичен мьютексу, но может использоваться для синхронизации между процессами.

  2. Счетный семафор: позволяет определенному количеству потоков одновременно использовать ресурс. Счетчик семафора инициализируется значением, равным количеству доступных ресурсов.

Принцип работы

Семафор управляется двумя основными операциями:

  • P (proberen, "попробовать"): операция уменьшает значение семафора. Если результат меньше нуля, поток блокируется до тех пор, пока ресурс не станет доступным.
  • V (verhogen, "увеличить"): операция увеличивает значение семафора, сигнализируя о том, что ресурс освобожден.

Пример использования семафора в C++

Рассмотрим пример использования счетного семафора для управления доступом к ресурсу, который может одновременно использоваться не более чем двумя потоками.

#include <iostream>
#include <thread>
#include <semaphore.h>
​
// Инициализация семафора с начальным значением 2
std::counting_semaphore<2> semaphore(2);
​
void accessResource(int threadID) {
    // Операция P: попытка занять ресурс
    semaphore.acquire();
    std::cout << "Thread " << threadID << " is accessing the resource." << std::endl;
​
    // Симуляция работы с ресурсом
    std::this_thread::sleep_for(std::chrono::seconds(1));
​
    std::cout << "Thread " << threadID << " is releasing the resource." << std::endl;
    // Операция V: освобождение ресурса
    semaphore.release();
}
​
int main() {
    // Создание и запуск нескольких потоков
    std::thread t1(accessResource, 1);
    std::thread t2(accessResource, 2);
    std::thread t3(accessResource, 3);
    std::thread t4(accessResource, 4);
​
    // Ожидание завершения всех потоков
    t1.join();
    t2.join();
    t3.join();
    t4.join();
​
    return 0;
}

Объяснение кода

  • std::counting_semaphore<2> semaphore(2);: создается счетный семафор, который позволяет одновременно использовать ресурс двум потокам.
  • semaphore.acquire();: операция P, которая уменьшает значение семафора. Если значение становится меньше нуля, поток блокируется.
  • std::this_thread::sleep_for(std::chrono::seconds(1));: симуляция работы с ресурсом, чтобы показать, как потоки занимают ресурс на некоторое время.
  • semaphore.release();: операция V, которая увеличивает значение семафора, сигнализируя о том, что ресурс освобожден.

Применение

Семафоры широко используются в системах, где необходимо управлять доступом к ограниченным ресурсам, например, в операционных системах, базах данных и сетевых приложениях. Они помогают избежать состояний гонки и обеспечивают безопасное и эффективное использование ресурсов.

Тема: Многопоточность / Синхронизация
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки