Just studied the different examples on using semaphores in the Tanenbaum book. Consider a non-trivial one like the solution given for the Dining Philosopher's problem. Sitting and staring at the algorithm for hours helps you understand it but not in such a way that you can recall it at a later time. Nor is it easy to find flaws in these algorithms just by inspection. I think that the only way to get good at using semaphores intelligently is to spend lots of time programming and debugging with them. If you don't use it you lose it.
Race conditions are painful because of their unpredictability.