A lock free queue still helps to have, even if you use an explicit semaphore or futex to synchronize threads at a higher level. A producer can queue up multiple items per post, and a consumer can empty the queue between pends. Without the lock free queue, the queue itself would have to be protected by a mutex. It's actually nice when lock free data structure implementations leave OS level synchronization up to the caller. It makes the implementation more generally useful and portable. It's perhaps a less obvious example of "dependency injection".