ch3 sharing data between threads

3.1 problems with sharing data between threads
3.1.1 the definition race condition which is problematic
3.1.2 avoide problematic race conditions
1) protection
2) lock-free
3) transaction

3.2 protecting shared data with mutexes

3.2.1 using mutex
std::mutex std::lock_guard
3.2.2 structuring code for protecting shared data
mutex and data within same class
3.2.3 race condition inherent in the interfaces
the exception free stack: split the top and pop, because if pop return the value, the poped element's copy constructor could throw exception.
but the split cause interface problematic race conditions.
 1) pass by reference which avoid the copy constructor,
 2) only support exception free copy constructor or move consturctor.
 3) return the pointer rather than the value which eliminating the copy constructor.(return std::shared_ptr)

question is:
std::make_shared<T>(?) what is the parameter type???
i think the only thing would be std::make_shared<T>(new xxx) never thought it could be used like this?

3.2.4 dead lock
a waiting b, b waiting a.
how to avoid it use:
std::lock(a_lock, b_lock);
std::lock_guard a_guard(a_lock, std::adpot_lock);
std::lock_guard b_guard(b_lock, std::adpot_lock);
std::lock_guard the second parameter used to notify the lock guard that the lock is locked and is adpoted from other.

std::lock is exception-aware if a_lock is locked, but lock b_lock failed with exception, a would unlocked.

3.2.5 futher guidelines for avoiding deadlocks
the lock hierarchy -- lock with the same order to avoide the deadlock
which could also apply to threads.

3.2.6 flexible locking with std::unique_lock
std::unique_lock<std::mutex> lock(mutex, std::defer_lock)

3.2.7 transferring mutex ownership between scopes
std::unique_lock is movable but not copyable.
return from a function e.g.

3.2.8 locking at an appropriate granularity
fine-grained and coarse-grained. more performance and maybe problematic race condictions
e.g. the comparsion example

3.3 alternatives for protecting share data

3.3.1 initialization
the lazy initalization
std::shared_ptr/double check pattern(why race condition)/c++11 static singleton pattern?(why pre would fail)
std::once_flag std::call_once it is just like the objective-c's dispatch_once
how does these thing implemented?

3.3.2 protecting rarely updated data structures.
std::shared_mutex std::shared_lock
need performance profiler

3.3.3 recursive lock
does not recommand if need you should rethinking the design

评论