Data Structures & Concurrency

  • A data structure has multiple elements
    • Multiple threads may access these elements
    • These accesses can conflict
    • Locks or atomic operations may be needed

Modifying Operations

  • May affect other parts of the object

  • Linked list

    • Data stored in a chain of nodes
    • Adding or removing an element modifies the surrounding nodes
  • Vector / String / Dynamic Array

    • Data stored in memory block
    • Adding or removing elements moves the following elements in memory
    • Adding elements may cause the block to be reallocated
  • If other threads are accessing those elements

    • Pointers and references may "dangle"
    • Iterators may become invalidated

Basic Thread Safety Guarantee

  • STL containers are "memory objects"

  • Concurrent reds of the same object are safe

    • Many threads can read from object X
  • A single write of an object is safe

    • One thread can write to object X
    • Provided no other threads access X concurrently
  • Concurrent reads and writes of the same object are not safe

    • One thread writes to object X
    • Other threads must not access X during this operation

Coarse grained locking

  • Locks the entire object

    • Easy to do
    • Requires no change to the data structure
  • Sometimes the only option

    • A variable of built-in type
    • Types in the C++ Standard Library
    • Types provided by other programmers, if we cannot modify them
  • In effect, all code that accesses the object will be single threaded

    • Serial code

Fine grained locking

  • We can choose which parts of the object to lock

    • We only lock some of the elements
  • This is known as "fine-grained locking"

    • Allows concurrent access
    • Requires writing extra code
    • Requires careful design
    • Increases cost of created object (mutex initialization)