This is a nice little book on the use of semaphores. It certainly goes far beyond the classical synchronization/coordination problems inspired from unhealthy hygiene habits (dining philosophers and the like). It offers many problems and their solutions, and for people who enjoy concurrent/parallel programming (especially shared-memory multi-threading) it's very fun to read.
However, I think I have spotted two issues with the book:
1. using python as the main language is not a good idea since the "standard" python distribution comes "locked" with the infamous GIL (Global Interpreter Lock) that never lets more than one thread actually run on the Python Virtual Machine, which essentially means Python is not well-suited to study concurrency.
2. The "Pass the Baton" pattern seems broken, given the understanding that we now have of memory models, and how monitors or any other synchronization primitive essentially act as communication primitives between threads establishing "happens-before" relations between events across threads. This strategy where one thread can acquire a lock but another thread will release it, means that possible changes made by the first thread (after the lock acquisition) will never be made visible to the other threads since it is not the same thread that will release the lock. In fact, I have written a java implementation of the "Sushi Bar" problem as advocated in the book using the "Pass the Baton" pattern, that doesn't respect the max. 5 customers constraint. So, my advice is: at least where "Pass the Baton" is used as a pattern of solution in a problem, beware of bugs relating to variable changes visibility issues.