C++(C11)

Concurrency and Parallelism

Concurrent programming provides a way for us to devise a solution to a problem (optionally) in parallel. If we structure the program so that it can be executed concurrently, then on a machine that supports parallelism, we can execute the program in parallel. Therefore, concurrency focuses on the design structure of the program, while parallelism refers to the state in which the program runs. Concurrent programming is a programming method that divides a program into small pieces for independent execution.

The C++ standard does not provide native support for multi-process concurrency, so C++ multi-process concurrency relies on other APIs - which need to be dependent on the relevant platform.


The C++11 standard provides a new thread library that includes classes for managing threads, protecting shared data, synchronizing operations between threads, and low-level atomic operations. The standard greatly improves the portability of the program. In the past, multithreading depended on the specific platform, but now there is a unified interface for implementation.

  • <thread>  : Contains the std::thread class and the std::this_thread namespace. Functions and classes for managing threads are declared in .
  • <atomic>  : Contains the std::atomic and std::atomic_flag classes, as well as a set of C-style atomic types and functions for C-compatible atomic operations.
  • <mutex>  : Contains classes related to mutexes and other types and functions
  • < future >  : Contains two Provider classes (std::promise and std::package_task) and two Future classes (std::future and std::shared_future) and related types and functions.
  • <condition_variable>  : Contains classes related to condition variables, including std::condition_variable and std::condition_variable_any.

Thread

default (1)
thread() noexcept;
initialization (2)
template <class Fn, class... Args>
explicit thread (Fn&& fn, Args&&... args);
copy [deleted] (3)
thread (const thread&) = delete;
move (4)
thread (thread&& x) noexcept;
  • (1). The default constructor creates an empty thread execution object.
  • (2). Initialize the constructor, create a thread object, the thread object can be joinable, the newly generated thread will call the fn function, the parameters of the function are given by args.
  • (3). Copy constructor (disabled), which means that thread cannot be copy constructed.
  • (4). Move constructor, move constructor, x does not represent any thread execution object after successful call.
  • Note: thread objects that are joinable must be joined by the main thread or set to detached before they are destroyed.

 

 

smart pointer

shared_ptr

shared_ptr is a standard shared ownership smart pointer, allowing multiple pointers to point to the same object. Defined in the memory file (not memory.h), with a namespace of std.

  shared_ptr is to solve the limitation of auto_ptr on object ownership (auto_ptr is exclusive), and provides smart pointers that can share ownership on the mechanism of using reference counting, of course, this requires additional overhead:
  (1) shared_ptr objects In addition to including a In addition to the pointer to the owned object, it must also include a pointer to a reference-counted proxy object.
  (2) The time overhead is mainly in initialization and copy operations. The overhead of * and -> operator overloading is the same as that of auto_ptr.
  (3) Overhead Not a reason why we don't use shared_ptr, never do premature optimizations until the profiler tells you that.

  Instructions:

You can use the template function make_shared to create an object. Make_shared needs to specify the type (in '<>') and parameters (in '()'). The passed parameters must match the constructor of the specified type. For example:
  std::shared_ptr<int > sp1 = std::make_shared<int>(10);
  std::shared_ptr<std::string> sp2 = std::make_shared<std::string>("Hello c++");
You can also define variables of type auto to save the result of make_shared.
  auto sp3 = std::make_shared<int>(11);
  printf("sp3=%d\n", *sp3);
  auto sp4 = std::make_shared<std::string>(" C++11");
  printf("sp4=%s\n", (*sp4).c_str());

 

atomic instruction

Atomic instructions are instructions that are indivisible to software

Atomic instructions (x are std::atomic<int>) effect
x.load() Return the value of x.
x.store(n) Set x to n and return nothing.
x.exchange(n) Set x to n and return to the value before setting.

x.compare_exchange_strong(expected_ref, desired)

If x is equal to expected_ref, set it to desired and return success; otherwise, write the latest value to expected_ref and return failure.
x.compare_exchange_weak(expected_ref, desired) May have spurious wakeup compared to compare_exchange_strong .
x.fetch_add(n), x.fetch_sub(n), x.fetch_xxx(n) x += n, x-= n (or more instructions), return the value before modification.

race condition、ABA problem、memory fence

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326846748&siteId=291194637