Multi-line libraries in c++11

Source: Internet
Author: User
Tags mutex semaphore

One, Linux thread synchronization

Threads are supported at the operating system level, so multithreaded learning advice is to find a Linux system programming class book to understand that Linux provides multi-threaded API. It is painful to write multithreaded programs entirely using system calls, and there are many multithreaded libraries that are packaged well, but understanding multithreaded systems can be very useful for learning to write multi-threaded applications. In general, Linux provides four types of systems for multiple programs, thread creation, destruction (threads), thread synchronization (mutex), conditional amount (cond), Semaphore (SEM)).

    • mutexes enable synchronization between threads through the mechanism of locking. A mutex is a special variable that can be locked and unlocked. The mutex ensures that only one thread accesses the shared resource between threads at the same time. (The locking and unlock of the actions corresponding to the mutex)
    • The use of conditional variables requires a combination of mutex, condition variable, condition. When a thread is viewing a condition, it needs to be locked with a mutex, and the condition variable (wait) operation automatically blocks the thread when the condition satisfies the thread to perform an operation that does not satisfy the condition. When another thread modifies the condition, it activates the blocked thread, blocking the thread from re-evaluating the condition. The detection of conditions must be done under the protection of the mutex. The action that corresponds to the condition variable is wait,try_wait.
    • Mutual exclusion is only two states of lock and unlock, the semaphore can be understood as a special variable with multiple states, there are waiting for the semaphore (wait) and releasing (release) two operations, respectively, the corresponding signal volume minus 1 and plus 1.

Reference: Three ways to synchronize Linux threads

Second, c++11 thread synchronization

C++11 supports multithreaded operations from a language level, which is essentially a encapsulation of system calls, but greatly facilitates the developer.

1. <thread>

Threading class Thread, using RAII style to manage the creation and destruction of threads. When a thread is created, the thread is automatically destroyed by the code snippet (function, LAMDA expression) and arguments that the thread is going to execute.

2. <mutex>

A. The operating system provides a mutex that can set properties, C++11 provides four types of mutex based on mutext properties, respectively

    • Std::mutex, the most common, common mutex (default property),
    • Std::recursive_mutex, allows the same thread to use recursive_mutext multiple locks, and then unlock using the same number of unlock operations. Multiple locks on a mutex can cause a deadlock
    • Std::timed_mutex, adds the time attribute on the mutex. Added two member functions Try_lock_for (), Try_lock_until (), receive a time range respectively, and then for a given time if the mutex is locked, the thread blocks, exceeds the time, and returns false.
    • Std::recursive_timed_mutex, adding recursion and time attributes

B. Mutex member function plus lock unlock

    • Lock (), the mutex is locked, if the mutex is locked, the thread is blocked
    • BOOL Try_lock (), attempts to lock, if the mutex is not locked, performs a lock operation, returns True, if the mutex is locked, returns false, the thread does not block.
    • void unlock (), Unlocking mutex

C. Mutex Raii-type locking unlock

    • Std::lock_guard, a class that manages mutexes. When an object is built, it is automatically joined to the mutex until it leaves the scope of the class and is unlocked when the destructor is completed. The RAII stack object guarantees that the mutex can be unlocked in the case of an exception Lock_guard object.
    • Std::unique_lock is similar to Lock_guard, but is more powerful than the Lock_guard function. For example, Std::unique_lock maintains the state of the mutex, can be accessed via bool Owns_lock (), and returns True when locked, otherwise false

3, Condition_variable

the use of conditional variables is combined with conditions, mutexes, and conditional variables. A thread uses a mutex to lock before the condition is detected, and when a condition is met, the thread uses the condition variable's wait operation to enter the blocking state. When other threads modify the condition, the conditional variable is activated to block the thread, and the blocking thread's re-lock detection condition is detected. The condition variable provides two operations for wait and notify.

1 //Condition_variable Example2#include <iostream>//Std::cout3#include <thread>//Std::thread4#include <mutex>//Std::mutex, Std::unique_lock5#include <condition_variable>//std::condition_variable6 7 Std::mutex MTX;8 std::condition_variable CV;9 BOOLReady =false;Ten  One voidPRINT_ID (intID) { AStd::unique_lock<std::mutex>lck (MTX); -    while(!Ready ) cv.wait (LCK); -   // ... theStd::cout <<"Thread"<< ID <<'\ n'; - } -  - voidGo () { +Std::unique_lock<std::mutex>lck (MTX); -Ready =true; + Cv.notify_all (); A } at  - intMain () - { -Std::thread threads[Ten]; -   //Spawn Threads: -    for(intI=0; i<Ten; ++i) inThreads[i] =Std::thread (print_id,i); -  toStd::cout <<"Ten threads ready to race...\n"; +Go ();//go! -  the    for(auto&th:threads) Th.join (); *  $   return 0;Panax Notoginseng}

4. Signal Volume (CSemaphore)

C++11 Multi-line libraries does not provide a semaphore class, but it is easily implemented by conditional variables and mutexes themselves.

//Semaphore classclassCSemaphore {Private: std::condition_variable CV;    Std::mutex Mutex; intvalue; Public: CSemaphore (intinit): Value (init) {}voidWait () {Std::unique_lock<std::mutex>Lock(mutex);  while(Value <1) {cv.wait (Lock); } Value--; }    BOOLtry_wait () {Std::unique_lock<std::mutex>Lock(mutex); if(Value <1)            return false; Value--; return true; }    voidPost () {{Std::unique_lock<std::mutex>Lock(mutex); Value++;    } cv.notify_one (); }};

5. Atomic Operation <atomic>

For multi-threaded shared data storage read and write, multi-threaded instruction intersection may cause unknown errors (undefine behavior), need to limit the concurrent programs in a particular order to execute, in addition to the previously described mutex lock manipulation, you can also use the principles provided in C++11 operation (Atomic). Atomic operations make it possible for a thread to perform an operation on the shared data in either step or not.

A. std::atomic_flag is a bool atom type with two states: Set (Flag=true) and Clear (Flag=false), which must be atomic_flag_init initialized at this time flag is clear state, Equivalent to static initialization. Once the Atomic_flag is initialized, there are only three operations: Test_and_set,clear, destructors, all atomic operations. Atomic_flag::test_and_set check flag is set, if set to return true, if not set flag is set to True and then return FALSE. Atomic_clear () Clear flag flag is flag=false. Operations such as copying, assigning, and so on are not supported, as are all atomic types because operations between two atomic types are not guaranteed to be atomized. The operability of Atomic_flag is not strong, which leads to its limitation of application and atomic<bool>.

B.atomic<t> template class. T must satisfy trivially copy type. The Copy/Move/assignment function is defined, there is no virtual member, and the base class or any other non-static member is trivally copyable. Typical built-in type bool, int, etc. belong to the trivally copyable type. Note that some atomic operations may fail, such as atomic<float>, Atomic<double>, and no atomic arithmetic operations against floating-point numbers.

The atomic<t> is especially specific for integers and pointers. Integers include Har, signed char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned lo Ng Long, char16_t, char32_t, wchar_t. Since in practice, more than one atomic type is an integer, the following is an integer atom type of the atomic type of operation function

    • constructor function. The constructor passes an integer of type T, Initializes a Std::atomic object, and the copy constructor is disabled.std::atomic <int> foo = 0;
    • Std::atomic::operator= (T val), an assignment operation function. A variable of type T can be assigned to the corresponding atomic type variable, which is equivalent to an implicit conversion, and the operation is atomic.
    • Std::atomic::is_lock_free, determines whether the Std:atomic object has lock-free characteristics and does not cause the thread to block when multiple lines Cheng the object. (It is possible to use some kind of transactional memory to transactional the Lock-free feature).
    • Store modifies encapsulated value, sync specifies memory sequence, default is sequential consistency
    • Load and store correspond, read the encapsulated value
    • Exchange Reading and modifying the encapsulated value, Exchange replaces the value specified by Val with the value encapsulated by the atomic object, and returns the value encapsulated by the atomic object before it, and the entire process is atomic (so the exchange operation is also known as the read-modify-write operation )。 Sync parameter Specify Memory order

For integer specificity, some of the additional operational functions are:

    • Fetch_add, adds a value to the encapsulated value of an atomic object and returns the old value of an atomic object
    • Fetch_sub, reduces the value of an atomic object's encapsulation and returns the old value of an atomic object
    • Fetch_and, encapsulates the value of an atomic object with a value, and returns the old value of an atomic object
    • Fetch_or
    • Fetch_xor
    • Supports operator++, atomic object self-increment
    • Supports operator--, atomic object Self-reduction

6. Future

Reference: C + + concurrency combat 13:std::future, Std::async, std::p romise, std::p ackaged_task

Multithreaded programming, on the one hand to pay attention to multi-thread shared variable access security, on the other hand, some asynchronous tasks will have the result of delivery. The C++11 standard provides several asynchronous task handling mechanisms. Normally the thread cannot return directly to the executing structure (which can be passed through the application, pointers), while in asynchronous processing many times a thread (privider) creates a thread (executor) to handle a task, provider at some point acquires executor execution result, If executor does not complete the task, the provider thread blocks the wait until the executor thread finishes the task and returns the result.

Std::future can be used to get the result of a task in an asynchronous task, but it just gets the result, and the real asynchronous call needs to mate with Std::async,std::p ackaged_task,std::p romise. Async is a template function, Packaged_task and promise are template classes, and typically template instantiation parameters are task functions.

A. AYSNC function +future mode

std::future<bool> fut = Std::async (is_prime,313222313);

Here Async automatically creates a background thread, executes the task Is_prime function, and saves the results in Myfuture, where the future template parameter is consistent with the task return type bool.

B.packaged_task+future

std::p Ackaged_task contains two of the most basic elements inside. One, the task is wrapped, the task is a callable object, function object, function pointer. Second, shared state, which holds the return value of the task and asynchronously accesses the shared state using the Std::future object.

You can obtain the Std::future object associated with the shared state by using std::p ackged_task::get_future. After calling the function, two objects share the same shared state, as explained below:

    • std::p The Ackaged_task object is an asynchronous Provider that sets the shared state value at some point by invoking the wrapped task.
    • The Std::future object is an asynchronous return object that allows you to get a shared state value and, of course, waits for the shared state flag to become ready when necessary.

std: The life cycle of the shared state of the:p Ackaged_task continues until the last object associated with it is freed or destroyed.

Specific example reference: http://www.cplusplus.com/reference/future/packaged_task/

C.promise + Future

Aync and Packaged_task, is the result of the provider thread getting the executor thread. Promise is a provider thread passing parameters through a future object item executor thread.

The Promise object can hold the value of a type T, which can be read by the future object (possibly in another thread). Promise object constructs can be associated with a shared state (typically Std::future) and a value of type T can be saved on the associated shared state (std::future).

You can get the future object associated with the Promise object by Get_future, and after calling the function, two objects share the same shared state

    • The Promise object is an asynchronous Provider that can set the value of a shared state at a certain point in time.
    • The future object can return the value of the shared state asynchronously or, if necessary, block the caller and wait for the shared status flag to become ready before the shared status can be obtained.
1#include <iostream>//Std::cout2#include <functional>//Std::ref3#include <thread>//Std::thread4#include <future>//std::p romise, Std::future5 6 voidPrint_int (std::future<int>&fut) {7     intx = Fut.Get();//gets the value of the shared state.8Std::cout <<"Value:"<< x <<'\ n';//print value:10.9 }Ten  One intMain () A { -std::p romise<int> Prom;//generates an std::p romise<int> object. -std::future<int> fut = prom.get_future ();//associated with the future. theStd::thread T (print_int, std::ref(fut));//give the future to another thread T. -Prom.set_value (Ten);//sets the value of the shared state, where it is synchronized with the thread T. - T.join (); -     return 0; +}

Multi-line libraries in c++11

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.