Consider the use of producer-consumer queues or message queues. For your example, you can use a queue in two ways:
Changes to the Subject are queued. When something updates the subject, it puts the new state in the queue and returns immediately. This way, the updater does not block while the observers are notified. You will need a thread that continuously dequeues state changes and updates observers.
Notifications to Observers are queued. Each observer has a queue where subject state-change notifications are posted.
If you are using the Qt library, you can use the signals & slots mechanism with the Qt::QueuedConnection connection type. The slot goes through the receiver's event queue and is executed in the receiver's thread. This way, the sender does not block while the receivers execute their respective slots.
Your program might be a good candidate for the Actor model (paradigm). Here are some C++ libraries that implement the actor model:
- Theron
- libcppa (C++11 based)
- Asynchronous Agents Library (Microsoft)
Your program might also be a good candidate for the Dataflow paradigm. Check out the proposed Boost Dataflow library, which supports threading.
I don't have a book to recommend, but check out Herb Sutter's series of Dr Dobbs articles on C++ concurrency.