Some details about Std::thread and std::condition_variable

Source: Internet
Author: User
Tags cmath

Also considered a lot of multi-threaded related information, but has been some of the details are not too good grasp, such as Std::thread thread really started to run the timing, such as join, Detch and other real role.

Followed by "Cplusplus Concurrency in Action_practical multithreading" after the relevant details, the following record some of the gains obtained by individuals.

Std::thread real time to start running

Here is a demo of a producer consumer model based on conditional variables and mutexes that I'm trying to write, starting here

#include <iostream>#include<thread>#include<unistd.h>#include<vector>#include<mutex>#include<condition_variable>#include<cmath>std::vector<int>Resource;std::mutex m;std::condition_variable CV;voidthread_procedure () { while(true){        intN;  while(true) {Std::unique_lock<std::mutex>ul (m); Cv.wait (ul,[&]{return!resource.empty ();}); if(!Resource.empty ()) {N=Resource.back ();                Resource.pop_back ();  Break; }        }        intres =0;  for(inti =0; i<n; ++i) {            //sleep (2);res+=i; } Std::lock_guard<std::mutex>ll (m); Std::cout<<"The From Thread"&LT;&LT;STD::THIS_THREAD::GET_ID () <<", "<<"The sum of 0+1+2+...+"<<n<<" is"<<res<<Std::endl; }}intMain () {Std::thread tt[5];  for(inti =0; i<5; ++i) {Tt[i]=Std::thread (thread_procedure); }         for(inti =0; i<5; ++i)    {Tt[i].join (); }     while(true) {Std::lock_guard<std::mutex>LG (M); Resource.push_back (rand ()% -);    Cv.notify_one (); }}

This code uses a Std::mutex and a std::condition_variable to control the corresponding thread, attempting to implement a simple print function.

But at run time the code will be stuck at the producer, that is, the while loop after the join code does not run down ...

This involves almost the Std::thread line libraries The mechanism for thread initiation and the true semantics of joins.

Here is a GNU implementation code for Std::thread:

classthread{ ... Public: Thread () noexcept=default; Thread (thread&) =Delete; Thread (Constthread&) =Delete; Thread (thread&&__t) noexcept {swap (__t);} Template<typename _callable, TypeName ... _args>ExplicitThread (_callable&& __f, _args&&... __args) {_m_start_thread (_m_make_routine (std::__bind_simple (Std::forward<_Callable>(__f), Std::forward<_Args>(__args))); }    ...};

You can see that the thread's constructor passed in a _callable callable object and related parameters, and then wrapped it using std::__bind_simple, which is equivalent to Std::bind, and then uses _m_start_ Thread directly using the platform-related thread implementation to open this thread!

From here we can see that the new thread is open when each std::thread construct is complete !

The function of the join function is to wait for the join's thread to finish and continue running subsequent code after the join returns.

This way the code above will be stuck, and the resource pool runs out after the new thread is opened, and then the thread that starts up is blocked on the condition variable, and the subsequent production process inside the while loop is due to the join function not running until the thread that has been opened is terminated.

The entire program stops there when all the threads are blocked.

The solution to this problem is also simple, another producer thread on the line, the following code:

#include <iostream>#include<thread>#include<unistd.h>#include<vector>#include<mutex>#include<condition_variable>#include<cmath>std::vector<int>Resource;std::mutex m;std::condition_variable CV;voidthread_procedure () { while(true){        intN;  while(true) {Std::unique_lock<std::mutex>ul (m); Cv.wait (ul,[&]{return!resource.empty ();}); if(!Resource.empty ()) {N=Resource.back ();                Resource.pop_back ();  Break; }        }        intres =0;  for(inti =0; i<n; ++i) {Res+=i; } Std::lock_guard<std::mutex>ll (m); Std::cout<<"The From Thread"&LT;&LT;STD::THIS_THREAD::GET_ID () <<", "<<"The sum of 0+1+2+...+"<<n<<" is"<<res<<Std::endl; }}voidproducer () { while(true) {Std::lock_guard<std::mutex>LG (M); Resource.push_back (rand ()% -);    Cv.notify_one (); }}intMain () {Std::thread tt[6];  for(inti =0; i<5; ++i) {Tt[i]=Std::thread (thread_procedure); } tt[5] =Std::thread (producer);  for(inti =0; i<6; ++i)    {Tt[i].join (); }}

In this case, all worker threads are turned on before the join function is called, and there is no such problem.

Some details about Std::thread and std::condition_variable

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.