Семафор охватывает различные варианты использования, кроме мьютекса.
С мьютексом вы были бы правы. Мьютекс обычно используется для предотвращения одновременного выполнения критических разделов в коде. Конкретный поток получит мьютекс в начале критического раздела и освободит его, когда он снова покинет критический раздел. Наличие мьютекса, выделяемого другим потоком, чем тот, который его приобрел, будет означать, что критический раздел связан с несколькими потоками, что, скорее всего, не так, как вы хотите что-то делать.
Вариант использования для семафора несколько отличается. Это сигнализирует о наличии ресурса. Поток, который должен потреблять ресурс, получит семафор, который концептуально приобретает базовый ресурс. Если ресурсы недоступны, то сборка будет блокироваться.
Теперь, когда сценарий, в котором мы говорим о фиксированном наборе ресурсов (например, набор доступных портов ввода-вывода), имеет смысл также для того, чтобы поток-прилив снова выпустил ресурс. Я приобретаю порт, выполняю некоторую работу и освобождаю его, когда делаю так, чтобы другие потоки могли работать над ним.
Но это не единственный вариант использования семафоров. Подумайте о производителе/потребителе: нить производителя может предоставить ресурсы (например, элементы, которые поставлены в очередь для обработки рабочим потоком), и потребительский поток примет их. В этих сценариях потребляемые ресурсы обычно исчезают, поэтому вы не освобождаете свои ресурсы после их приобретения. Вместо этого производящая нить вызывает освобождение, чтобы указать, что есть материал, доступный для потребления. Затем потребитель призывает приобретать заявку на созданный ресурс и обрабатывать его. Производитель никогда не будет называть покупку, и потребитель никогда не будет вызывать выпуск.