Osn c++0x (v)--thread, mutex, condition_variable

Source: Internet
Author: User
Tags closure

Familiar with c++98 friends, should all know, in c++98 no thread, mutex, condition_variable these concurrency related features support, if you need to write multi-threaded related programs, you have to rely on different platforms on each of the APIs provided , the problem is that the cross-platform portability of the program is poor, often with a lot of #ifdef WIN32 similar macros to distinguish between different platforms, make the program difficult to see. One of C++0x's original intentions was to make C + + more powerful and easier to use. Now that the hardware is so developed, concurrency is already commonplace in programming, and if C + + does not support these concurrency-related features, it really is out. Now, the Gospel of C + + programmers, C++0X provides support for thread, mutex, condition_variable these concurrency-related features, and the code for this piece of multithreading can be completely cross-platform, and because C + + 0x packages are better, and the code is very concise to write. Let's start with today's content.

      • 1. Thread

Write too many threads of the application of the friend, I believe that the thread itself is not unfamiliar, here is not the thread itself to do too much explanation, to introduce the use of thread c++0x in the main. Let's look at the following example:

12345678910111213141516171819202122232425262728293031323334
#include < iostream> #include < string> #include < thread> class Printer{public:    void Print (int id, s td::string& name)    {           Std::cout < < "id=" << ID << ", name=" << name;    }   }; void Hello () {    std::cout << "Hello World" << std::endl;} int main () {    Printer p;    int id = 1;    std::string name ("Xiao5ge");    std::thread T1 (&printer::P rint, p, ID, name);    Std::thread T2 (Std::bind (&printer::P rint, p, ID, name));    std::thread T3 ([&]{p.print (ID, name);});     std::thread t4 (Hello);    T4.join ();    T3.join ();    T2.join ();    T1.join ();}

Let's take a look at the example above to illustrate the use of thread. The above four examples of T1-T4 are four ways to construct thread, and we hit introduce:

        • (1) This method is implemented by a variable parameter template, the first parameter is the address of the thread entry function, and the following parameters are passed in the order of the arguments in the function call. Here are the two points: first, the variable parameter template is also c++0x new features, will be described in the following article, second, the class member function of the first parameter is always this, so here the first parameter is the object itself.
        • (2) This way is to pass in a Std::function object, bind/function in the previous article has introduced, unfamiliar friends can first look at the c++0x series of the fourth chapter.
        • (3) This is a more common way of passing in a lambda expression, or a closure. About Lambda is also described in the previous article.
        • (4) This is the simplest and most common way to pass directly to a function, and a friend who writes too many threads should be most familiar with this approach.

The basic usage of c++0x thread is described above, and a few additional things to be aware of when using the process are as follows:

        • (1) If the parameters of the entry function are passed in as a reference or pointer, the user is required to ensure that the parameters are valid during the thread run. At the same time, if there are multiple lines routines access or modify these variables, users need to do a good job of synchronization to ensure consistency.
        • (2) on the above mentioned several constructs, the simple direct use 4, the complex recommendation Choice Order: 1->3->2, namely the variable parameter template way->lambda way->bind Way
        • (3) It is usually necessary to wait for a child thread to run out, and the mainline friend exits, so it is usually necessary to tune the join () of each child thread in the main thread.
      • 2. Mutex

mutexes implement the "mutex" semantics, in multi-threaded programs, often need to pass the lock mechanism to ensure data consistency, C++0X provides the following four kinds of semantic mutex:

        • (1) Std::mutex: Ordinary mutual exclusion lock, can not be used recursively
        • (2) Std::timed_mutex: Mutex with timeout, cannot be used recursively
        • (3) Std::recursive_mutex: Recursive Mutual exclusion lock
        • (3) Std::recursive_timed_mutex: Recursive mutex with timeout

With regard to the use of mutexes, we usually recommend the use of RAII (Resource acquisition is initialization), that is, at the time of the construction of the lock, when the destruction of unlock, do not recommend the direct explicit Lock/unlock, Because it is more prone to error. As a result, c++0x also provides two tool classes Std::lock_guard and Std::unique_lock to assist us with the use of mutexes, let's take a look at the specific use of the following example:

1234567891011121314151617
#include < mutex>//global Varsint data = 0;std::mutex Data_mutex; Thread 1{    std::lock_guard< std::mutex> Locker (Data_mutex);    data = 1;} Thread 2{    std::lock_guard< std::mutex> Locker (Data_mutex);    data = 2;}

From the above example, I believe that you can use the basic method of the mutex should be more clear, because the mutex itself is relatively simple, here no longer explain. Talking about the difference between Std::unique_lock and Std::lock_guard, Std::lock_guard only allows the use of Raii mode, and Std::unique_lock can call Lock/unlock after construction, More flexible, but the odds of using the error is also greater, so if there is no special need, it is usually recommended to use Std::lock_guard as much as possible.

      • 3. condition_variable

About Condition_variable, it is the semantics of today's three content is relatively complex, I have written an article about it, unfamiliar friends can first read the "condition variable (Condition variable) detailed" This article, Let's look at the condition variables to make it easier to understand what's behind it. We know that the condition variables are mainly used to modify the Shared_data after the multi-threaded communication, because the condition variable in multithreaded programming is very useful, so c++0x also added to the condition variable support, the following is the two different types of c++0x provided by the condition variables:

    • (1) condition_variable: Used in std::unique_lock< std::mutex> wait, more efficient.
    • (2) Condition_variable_any: Can be used on any mutex wait, more flexible, but less efficient than condition_variable.

Let's take a look at some examples of how conditional variables are used in c++0x:

 123456789101112131415161718192021222324252627282930313233 
//globalstd::atomic< bool> Is_finish (false); Std::mutex Finish_mutex;  Std::condition_variable finish_cond; //thread 1{std::unique< std::mutex> Locker (Finish_mutex); //    1. Loop wait while (!is_finish) {finish_cond.wait (locker); }  //2. Wait until prediction is true, loop inside Finish_cond.wait (Locker, []{return is_finish;});  //3.  Wait until Eithor prediction is true or timeout finish_cond.wait (Locker, Std::chrono::seconds (1), []{return Is_finish; }); } //thread 2{is_finish = true; //1. Notify one of the waiter Finish_cond.notify_one (); //
  2. Notify all the waiter Finish_cond.notify_all ();} 

The above example basically covers the main usage of the conditional variables provided by c++0x. Let's analyze each one to help you understand better:

    • (1) With regard to wait, there are three basic usages: the 1th is to wait on the specified condition until the condition is true notify to continue the subsequent logic, and the 2nd is the same as in French and 1th, but is not the user doing an explicit loop wait, When a user passes in a condition that needs to be met, wait waits until the condition is notify, and then returns to the following logic, which is understood to have a loop inside wait, and a 3rd usage that adds a closure semantics. Wait waits until the condition is true or timed out, and then returns to the following logic when it is notify.
    • (2) There are two types of notify: The 1th is Notify_one, which only wakes up a thread in wait; The 2nd type is Notify_all, which wakes up all the threads in wait, equivalent to a broadcast semantics.

The above is the main content of today, hope to be learning c++0x friends have help, honored!

Osn c++0x (v)--thread, mutex, condition_variable

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.