C++ Concurrency in Action

Published:

Reading Note of C++ Concurrency in Action

mind map

Introduction

thread-safe vs. re-entrant

they are independent concepts.

  • re-entrant means that whenever the code is run, the code will the

Thread Management

Managing threads

  • init thread with fuction
  • join
  • detach

    Exception

  • RAII

    Thread Arguments

  • pass arguments like function Always remember to check the argument passing, as the thread will copy the value to initialize the variable even you pass by reference and pointer. Using the std::ref when you need to pass by reference.

Transfering ownership of thread

  • std::move move only class

    Choosing number of threads at runtime

  • std::thread::hardware_concurrency()

    Identifying thread

  • thread.id

Sharing Data between Threads

Race condition

  • definition: multiple threads access same data, the order they access lead to undefined behaviour.

    Using mutex to avoid Race condition

  • RAII
  • dead lock
  • exception safe

    mutex ownership transfer

  • mutex is move only class ###

    Waiting in Threads

    wait for event with condition variable

    wait for one off event

    std::future

    std::async

    std::package_task

    std::promise

    wait for particular time period

    continuation for the then semantic

    std::experimental::future facilitate the then semantic with the std::experimental::future::then member function. if you want to pass arguments to the then function, you need to capture the arguments with lambda function. after the then function is called, the future becomes invalid. It’t an one off future.

    chaining of continuations

    the then return a std::experimental::future object, and therefore it can be chained into a sequential call. beware of the std::experimental::future returns a std::experimental::future and std::experimental::shared_future returns std::experimental::shared_future and remember the exception delivering rules in future.

    waiting multiple threads

    Memory Model in C++

    atomic types:

  • is_lock_free()

std::atomic_flag

atomic types are not guaranteed to be lock free, as different device may support different atomic instructions.

std::atomic_flag is always guaranteed to be lock free.

operations

  • initialze (atomic flag is always guaranteed to be initilized to ATOMIC_FLAG_INIT)
  • destroy(destructor)
  • clear()
  • test_and_set()
  • query previous value

A single operation on two distinct objects can’t be atomic.

  • copy constructor
  • copy assignment constructor

std::atomic<T*>

int array[4] = { 0, 1, 2, 3};
    std::atomic<int *> intPtr{ array };
    GTEST_LOG_(INFO) << "intPtr.fetch_add(2):" << *intPtr.fetch_add(2);
    GTEST_LOG_(INFO) << "intPtr++:" << *(intPtr++);
    GTEST_LOG_(INFO) << "intPtr:" << *intPtr;

    intPtr.fetch_add(2):0

[  INFO ] intPtr.fetch_add(2):0
[  INFO ] intPtr++:2
[  INFO ] intPtr:3