Смысл семафора со счетчиком в том, чтобы дать доступ к какому-то ресурсу только определенному количеству процессов. Остальные будут ждать в очереди, когда ресурс освободится.
Итак, для реализации семафоров будем использовать POSIX функцию sem_open():
#include <semaphore.h> sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
В функцию для создания семафора мы передаем имя семафора, построенное по определенным правилам и управляющие флаги. Таким образом у нас получится именованный семафор.
Имя семафора строится следующим образом: в начале идет символ "/" (косая черта), а следом латинские символы. Символ «косая черта» при этом больше не должен применяться. Длина имени семафора может быть вплоть до 251 знака.
Если нам необходимо создать семафор, то передается управляющий флаг O_CREATE. Чтобы начать использовать уже существующий семафор, то oflag равняется нулю. Если вместе с флагом O_CREATEпередать флаг O_EXCL, то функция sem_open() вернет ошибку, в случае если семафор с указанным именем уже существует.
Параметр mode задает права доступа таким же образом, как это объяснено в предыдущих главах. А переменной value инициализируется начальное значение семафора. Оба параметра mode и valueигнорируются в случае, когда семафор с указанным именем уже существует, а sem_open() вызван вместе с флагом O_CREATE.
Для быстрого открытия существующего семафора используем конструкцию:
#include <semaphore.h> sem_t *sem_open(const char *name, int oflag); , где указываются только имя семафора и управляющий флаг.
Пример семафора со счетчиком
Рассмотрим пример использования семафора для синхронизации процессов. В нашем примере один процесс увеличивает значение семафора и ждет, когда второй сбросит его, чтобы продолжить дальнейшее выполнение.