Process and thread fundamentals
qnx.com
qnx.com
Yet in the real world, it's thread pools that are the go to when you need to control the number of active threads. Can't think of any instances where semaphores would be a better choice over thread pools.
Also, I wish I knew how important a role CPU cache plays in performance. Another aspect which seems to be downplayed in academia.
That said, they are useful to manage concurrency in a finer-grained way than setting up and tearing down thread pools for short durations. E.g., imagine you have a pool of 100 cached threads and want to apportion no more than 5 of these to any one client.