C++ Concurrency
Threads
std::threaddetachwon't be able to manage the thread aside from any mutex or shared resources between the different threads. Those detached threads will only exit when the main process is terminated or when top level function exits.
Mutual Exclusion
std::mutex- protect shared resources and to prevent race conditions.
void lock();, block execution until the lock is acquired. usually not called directly: mutex wrapper are used to manage exclusive lockingbool try_lock();, returns immediately
std::recursive_mutex- The same thread cam lock an
recursive_mutexmultiple times without blocking
- The same thread cam lock an
Mutex Wrapper
std::lock_guard- It provides exclusive ownership of a mutex for a scoped duration.
- The lock is acquired upon construction and automatically released when the object goes out of scope.
lock_guard<mutex> guard(my_mutex)
std::unique_lock- It supports both exclusive ownership and shared ownership of a mutex.
- Allow manual unlocking, relocking, and transferring of ownership between different scopes or threads.
- Provides advanced functionalities like timed locking, condition variables, and deadlock avoidance.
unique_lock lock(mtx);
std::shared_lock- Multiple threads can acquire a shared lock on the same mutex
- Shared locking attempts block if the mutex is locked in exclusive mode
- Only usable in conjunction with
std::shared_mutex shared_lock lock(mtx);
-
std::scoped_lock- offers an alternative for
lock_guardthat provides the ability to lock multiple mutexes using a deadlock avoidance algorithm.
- offers an alternative for
- Shared mutexes are mostly used to implement read/write-locks
- Only read accesses are allowed when holding a shared lock
- Write accesses are only allowed when holding an exclusive lock
Atomic
std::atomic- An atomic type is mainly a type that implements atomic operations. thread safe and run independently of any other processes.
Futures
- promise
-
future
- returned by asynchronous operations (
async,packaged_task,promise)
- returned by asynchronous operations (
- task
promise<int> promise;
future<int> future = promise.get_future();
shared_future<int> shared_future = promise.get_future();
promise.set_value(10);
int val = future.get();
Memory Ordering
std::memory_ordermemory_orderspecifies how memory accesses are to be ordered around an atomic operation.- The default behavior of all atomic operations in the library provides for sequentially consistent ordering.
memory_order_seq_cstA load operation with this memory order performs an acquire operation, a store performs a release operation
- Relaxed ordering
- Release-Acquire ordering
- Release-Consume ordering
- Sequentially-consistent ordering