Paper
Paper: Real-world Concurrency
An excellent article by Bryan Cantrill and Jeff Bonwick on how to write multi-threaded code. With more processors and no magic bullet solution for how to use them, knowing how to write multiprocessor code that doesn't screw up your system is still a valuable skill. Some topics:
Know your cold paths from your hot paths.
Intuition is frequently wrong—be data intensive.
Know when—and when not—to break up a lock.
Be wary of readers/writer locks.
Consider per-CPU locking.
Know when to broadcast—and when to signal.
Learn to debug postmortem.
Design your systems to be composable.
Don't use a semaphore where a mutex would suffice.
Consider memory retiring to implement per-chain hash-table locks.
Be aware of false sharing.
Consider using nonblocking synchronization routines to monitor contention.
When reacquiring locks, consider using generation counts to detect state change.
Use wait- and lock-free structures only if you absolutely must.
Prepare for the thrill of victory—and the agony of defeat.
While I don't agree that code using locks can be made composable, this articles covers a lot of very useful nitty-gritty details that will up your expert rating a couple points.