Two main uses. First, managing a pool of identical resources: initialize the count to N (the number of available units, say N DMA buffers or N connection slots), and a task takes the semaphore (decrementing) to claim a unit and gives it back (incrementing) when done; when the count hits zero, further takers block until something is returned, naturally throttling usage to the available units without manual bookkeeping. Second, counting events so none are lost: if an ISR or producer can generate events faster than a consumer task drains them, a binary semaphore would coalesce multiple gives into one (the consumer sees "at least one" but loses the count), whereas a counting semaphore increments per event, so the consumer can take repeatedly and handle exactly as many events as occurred. So the mental model is "a binary semaphore says something happened; a counting semaphore says how many happened" or "how many units are available." You size the maximum count to the resource pool size or the worst-case event burst. It still has no ownership (it's a semaphore), so it's for counting/signaling, not for resource protection where you'd want a mutex's inheritance.
RTOS & Real-Time Concepts · Interview question
What is a counting semaphore good for?
A strong answer
What a weak answer sounds like
You know the answer. Do you know what gets you dinged?
Pro breaks down the answer most candidates actually give to this question — and the specific reason an interviewer marks it down. It’s the difference between sounding correct and sounding senior, on all 472 questions.
From the lesson
Mutexes & Semaphores
Coordinating concurrent tasks: a mutex for mutual exclusion (ownership + priority inheritance) vs a semaphore for signaling and counting, and why you give a semaphore from an ISR, not take a mutex.