C ++ 11 multi-thread Library

Source: Internet
Author: User
ArticleDirectory
    • 1. Create a thread using a global function
    • 2. Create a thread through a function object
    • 3. Create a thread using a Lambda expression
    • 4. Create a thread through the member function
    • 1. mutex
    • 2. Lock class
    • 3. Obtain the lock on multiple mutex objects
    • 4. STD: call_once STD: once_flag
    • 5. instance:
    • 1. STD: condition_variable can only wait for the condition variable of unique_lock <mutex>
    • 2. STD: condition_variable_any supports lock classes of any type.
    • 3.

 

 

Standard thread library, introduced in C ++ 11, including atomic operation library, mutex lock, and condition variable...

 

I. Thread library <thread>

 

There are four ways to create a thread:

 

1. Create a thread using a global function

The constructor of the thread class is a variable parameter constructor. The first parameter is a thread function, and the following parameter is the parameter of the thread function (the parameter is passed through the value transfer method, to reference the transfer, STD: ref () must be added ()).

Thread T1 (counter, 1, 6); // void counter (INT, INT );

 

2. Create a thread through a function object

// Class counter implements operator ()

1) thread T1 {counter (1, 20)}; // C ++ unified recommendation method

2) Counter C (1, 20 );

Thread T2 (C );

3) thread T3 (counter (1, 20 ));

 

Compare the first and third constructor methods if the constructor of the function object does not require any parameters. Thread T3 (counter (); no, because the compiler will think that you are declaring a function named T3. At this time, you can only use the first constructor.

 

3. Create a thread using a Lambda expression

I haven't learned lambda expressions yet. I skipped them ......

 

4. Create a thread through the member function

// Class Counter C ();

Thread t {& Counter: process, & c };

Generally, a class creates a background processing thread: thread t {& Counter: process, this };

 

Thread Local Storage thread_local Thread_local int N;

N is passed to the thread as a thread parameter. Each thread has a copy of N, which exists throughout the thread lifecycle and is initialized only once, just like static local variables.

 

 

Ii. atomic operation database <atomic>

 

Multi-threaded programming often requires the operation of shared memory, which leads to competition in the reading/writing process.

For example:

Int counter = 0;

............

++ Counter; // because ++ counter performs atomic operations from time to time, this operation is not thread-safe in multiple threads.

 

Use:

Atomic <int> counter (0); // equivalent to atomic_int counter (0 );

............

++ Counter; // at this time, multiple threads execute ++ counter is an atomic operation, which is thread-safe.

 Example:  Void Func (STD: Atomic < Int > & Counter ){  For ( Int I = 0 ; I < 1000 ; ++ I) ++ Counter ;}  Int  Main () {STD: Atomic < Int > Counter ( 0  ); STD: Vector <STD: thread>Threads;  For ( Int I = 0 ; I < 10 ; ++ I)  //  Thread parameters are always passed by value. To pass a reference, you must add STD: ref (). (Header file <functional>) Threads. push_back (STD: thread {func, STD :: Ref  (Counter )});  For (Auto & T: threads) T. Join ();  // Call join. If the thread is not finished, the main function is blocked here.  STD: Count < "  Result =  " <Counter < STD: Endl;  Return   0  ;}  /*  The call to join will cause the calling thread to be blocked. If you do not want the calling thread to be blocked but want to know whether the called thread is terminated, you should use other methods, such as message...  */ 

 

 

Iii. mutex <mutex>

To write multiple threads, you must pay attention to the operation sequence. If data cannot be shared by threads, you must provide a synchronization mechanism to ensure that only one thread can change data at a time. Using mutex to solve the competition conditions may lead to deadlocks.

1. mutex

1) non-scheduled mutexSTD: mutex STD: recursive_mutex

Lock (): attempts to obtain the lock and blocks it until the lock is obtained.

Try_lock (): attempts to obtain the lock and returns immediately. If the lock is obtained successfully, true is returned. Otherwise, false is returned.

Unlock (): Release the lock.

The difference between mutex and recursive_mutex is that the former cannot be obtained again after it is obtained. This will lead to a deadlock, and the latter can be obtained recursively. Note that the number of releases should be equal to the number of acquisitions.

 

2) timed mutex lockSTD: timed_mutex STD: recursive_timed_mutex

Lock (), try_lock (), unlock ()

Try_lock_for (rel_time): returns true if it is obtained within the specified relative time, and returns false if it times out.

Try_lock_until (abs_time): returns true if it is obtained within the absolute time of the system, and false if it times out.

The difference between timed_mutex and recursive_timed_mutex is the same as above.

 

2. Lock class

The lock class is a wrapper. The Destructor Automatically releases the associated mutex.

1) Simple lockSTD: lock_guard

The constructor requires the mutex to be obtained and blocks it until the lock is obtained.

 

2) complex locksSTD: unique_lock

Explict unique_lock (mutex_type & M ); //  Blocking until the lock is obtained.  Unique_lock (mutex_type & M, defer_lock_t) notest; //  Saves a mutex reference and does not immediately try to obtain the lock. The lock can be obtained later.  Unique_lock (mutex_type & M, try_to_lock_t ); //  Try to obtain the referenced mutex lock. If it is not obtained, it is not blocked. Unique_lock (mutex_type & M, adopt_lock_t ); //  The lock assumes that the thread obtains the referenced mutex lock and is responsible for managing the lock.  Template < Class Clock, Class Duration> Unique_lock (mutex & M, Const Chrono: time_point <clock, duration> & abs_time ); //  Try to get the lock until it exceeds the specified absolute time.  Template < Class Rep,Class Period> Unique_lock (mutex & M, Const Chrono: Duration <rep, period> & rel_time ); //  Try to obtain the lock until it exceeds the specified relative time. 

The unique_lock class also supports methods such as lock (), try_lock (), try_lock_for (), and try_lock_until.

You can use owns_lock () to check whether the lock is obtained. You can also use if to directly determine whether to obtain the lock for the unique_lock object because it defines the bool () operator.

 

3. Obtain the lock on multiple mutex objects

1) Generic lock Variable Parameter Template Function

Template <class L1, class L2, class... L3>

Void lock (L1 &, L2 &, L3 &...);

Locks in sequence. if an exception is thrown by a mutex, the acquired lock is unlocked.

 

2) Generic try_lock

Template <class L1, class L2, class... L3>

Int try_lock (L1 &, L2 &, L3 &...);

Call the try_lock of the mutex object in sequence, return-1 successfully, return the index starting from 0, and unlock the obtained lock.

 

The parameter sequence should be consistent each time; otherwise, deadlock may occur.

 

4. STD: call_once STD: once_flag

Ensure that the call_once scheduled function is executed only once.

 

5. instance:
 //  1. Simple lock  Mutex mmutex; lock_guard <Mutex> Mlock (mmutex );  //  2. timed lock Timed_mutex mtimemutex; unique_lock <Timed_mutex> mlock (mtimedmutex, chrono: milliseconds ( 200  ));  //  3. Generic  Mutex Mut1; mutex mut2; unique_lock <Mutex> Lock1 (Mut1, defer_lock_t (); unique_lock <Mutex> Lock2 (mut2, defer_lock_t ());  Lock  (Lock1, lock2 );  //  4. Double check lockAlgorithm(Instead of call_once) Class  Myclass {  Public  :  Void Init () {P = New   Int ( 0 ); Cout < "  Init  " < Endl ;}  Private  :  Int *P;} myclass  VaR  ;  Bool Initialized = False  ; Mutex mut;  Void  Func (){  If (! Initialized) //  One check  {Unique_lock <Mutex> Lock1 (MUT );  If (! Initialized)//  Two checks  {  VaR  . INIT (); initialized = True  ;} Cout < "  OK  " < Endl ;}  //  Check initialized twice. Before and after obtaining the lock, make sure that init is called only once. 

 

Iv. Condition variable <condition_variable> 1. STD: condition_variable can only wait for the condition variable of unique_lock <mutex>
 
Notify_one ();//Wake up one of the threads waiting for this condition variablePolicy_all ();//Wake up all threads waiting for this condition variable//1) The premise is that you have obtained the LK lock.//2) When wait is called, it will unlock LK and wait.//3) Lock lk after being awakenedWait (unique_lock <mutex> &Lk); wait_for (unique_lock<Mutex> & LK,ConstChrono: Duration <rep, period> &Rel_time); wait_until (unique_lock<Mutex> & LK,ConstChrono: time_point <clock, duration> & abs_time );
2. STD: condition_variable_any supports lock classes of any type. 3.
 //  For example, add data to the queue. When the queue is not empty, the background thread is awakened to process data. STD: queue <STD :: String > Mqueue; STD: mutex mmutex; STD: condition_variable mcondvar;  //  Thread for adding data to the queue Unique_lock <mutex> Lock  (Mmutex); mqueue. Push (data); mcondvar. policy_all ();  //  Data processing thread in the background Unique_lock <mutex> Lock (Mmutex );  While ( True  ){  //  1. Release the lock first. 2. Wait until it is awakened. 3. Wait until it gets the lock. Mcondvar. Wait ( Lock  );  //  Process... }

 

V. Future The promise/future model facilitates obtaining the results returned by the thread, inter-thread communication, and exception handling.

 

 

 

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.