Concurrency doesn't have many pitfalls.
Synchronizing access to shared data, however, is tricky.
Here are some questions anyone writing shared-data synchronization code should be able to answer:
- What is InterlockedIncrement?
- Why does InterlockedIncrement need to exist at an assembly language level?
- What is read write reordering?
- What is the volatile keyword (in c++) and when do you need to use it?
- What is a synchronization hierarchy?
- What is the ABA problem?
- What is cache coherency?
- What is a memory barrier?
"Shared everything" concurrency is an extremely leaky abstraction. Adopt shared nothing message passing instead.