1) A semaphore consists of a counter, a waiting list, and wait() and signal() methods. Wait() decrements the counter and blocks if it becomes negative, while signal() increments the counter and resumes a blocked process if the counter becomes positive.
2) The dining philosophers problem is solved using semaphores to lock access to shared chopsticks, with one philosopher designated as a "weirdo" to avoid deadlock by acquiring locks in a different order.
3) The producer-consumer problem uses three semaphores - one to limit buffer size, one for empty slots, and one for locks - to coordinate producers adding to a bounded buffer