In general, a semaphore is a 'counter' that you can increment or decrement atomically, and also wait for it to reach a certain value.
Semaphores are typically used in situations where you have a certain number of resources, and wish to be able to readily block on the condition of unavailible resources.
Generally, before trying to allocate a resource, you wait for the associated semaphore to become nonzero and decrement it atomically when it does become nonzero. After you have freed the resource, you increment the associated semaphore.