Use semaphores and deques to synchronize access to message queues.

This method avoids using sleep()s which slow down the system by
delaying message handling even when there are available messages.
The system is now more "event-based" and so doesn't require sleeping.
The receive() method also doesn't need to return None anymore when
the inbound_queue is empty.