Q:

Understanding semaphores

I am reading about semaphores in "Operating System Concepts" (for those of you who know it), and I thought I understood semaphores completely until I read this passage:

The critical aspect of semaphores is that they are executed
  atomically. We must guarantee that no two processes can execute wait
  and signal operations on the same semaphore at the same time.

And also:

If the hardware does not provide any special atomic instructions, we
  can employ any of the software solutions for the critical section
  problem, where critical sections consist of the wait and signal
  procedures.

This passage refers to the face to Signal and Wait operations must be atomic. 
I thought that the whole purpose of the semaphore was to let only one process in the critical section at any given time - if I have to use another algorithm (like the bakery algorithm), why do I also need the semaphore?
I realize my question might be confusing. If it is, its only because the subject is still vague to me, so even asking a question is a little hard.
Would love to read any clarifications...

A:

I think you're having trouble with the distinction between a semaphore and a mutex.  A binary semaphore can be implemented in the same way as a mutex, but they are actually for different purposes.  A semaphore protects a resource whereas a mutex strictly protects a block of code.  The distinction is often subtle.  
With semaphores you get into variations like counting semaphores so the idea that only one process can access a resource isn't always true.  You may want to block writes to one process or thread, but allow reads from multiple (reader/writer locks). 
I suggest you look at the wikipedia article on the subject.  It's actually quite good.
http://en.wikipedia.org/wiki/Semaphore_(programming)

A:

Atomicity is how you implement mutual exclusion. Say you only want one thread at a time entering a critical section of code. How do you do that? Well, you have a "locked/unlocked" indicator. And you force a thread to change the indicator from "unlocked" to "locked" before it enters the critical section of code.
But what stops two threads from both seeing that the indicator is "unlocked", both switching it to "locked" at the same time, and then both executing the critical section of code at the same time? And the answer is that the operation of switching from "unlocked" to "locked" must be atomic. That is, it must take place all at once so there is no way two threads can both succeed in changing the indicator to "locked".

