C ++ 11 concurrency Guide five (std :: condition_variable Detailed) C ++ 11 concurrency Guide five (std :: condition_variable Detailed)

Front three stresses " C ++ 11 concurrency guide two (std :: thread Detailed) ", " C ++ 11 concurrency guide three (std :: mutex Detailed) " introduced the std :: thread, std :: mutex, std :: future and other related content, I believe readers of multi-threaded programming in C ++ 11 has a basic understanding, this article will introduce the C ++ 11 standard <condition_variable> header file inside the class and related functions.

<Condition_variable> main header contains the classes and functions relating to the condition variable. Related classes include std :: condition_variable and std :: condition_variable_any, there are enumerated type std :: cv_status. Also included are a function of std :: notify_all_at_thread_exit (), below are brief or more types.

std :: condition_variable class presentation

std :: condition_variable condition variable is defined more about the condition variable reference Wikipedia . Use Pthread library pthread_cond under Linux _ * () function provides information on the condition variable functions, Windows reference is  the MSDN .

When a wait function std :: condition_variable object is called, it uses std :: unique_lock to lock the current thread (via std :: mutex). The current thread will always be blocked until another thread calls a notification function on the same std :: condition_variable object to awaken the current thread.

std :: condition_variable regularly use std :: unique_lock <std :: mutex> wait, if necessary using additional lockable type, may be used std :: condition_variable_any classes will be mentioned later herein, std :: condition_variable_any usage.

First we look at a simple example

 
#include <iostream> // std :: cout 
#include <the Thread> // std :: the Thread 
#include <mutex> // std :: mutex, std :: unique_lock 
#include <condition_variable> // std :: condition_variable 

std :: mutex mtx;. // global mutex 
std :: condition_variable cv;. // global variable conditions 
bool ready = false; // global flag. 

void do_print_id (int ID) 
{ 
    STD unique_lock is :: <STD :: mutex> LCK (mtx); 
    the while (! READY) // If the flag is not true, then wait ... 
        cv.wait (LCK); // current thread is blocked, when the global flag becomes true, 
    / / thread wakes up, printing continues down the thread number id. 
    STD :: COUT << "thread" id << << '\ n-'; 
} 

void Go () 
{ 
    STD unique_lock is :: <std::mutex> lck(mtx); 
    READY = to true;// set the global flag is true.
    cv.notify_all(); // 唤醒所有线程.
}

int main()
{
    std::thread threads[10];
    // spawn 10 threads:
    for (int i = 0; i < 10; ++i)
        threads[i] = std::thread(do_print_id, i);

    std::cout << "10 threads ready to race...\n";
    go(); // go!

  for (auto & th:threads)
        th.join();

    return 0;
}
 

Execution results are as follows:

 
concurrency ) ./ConditionVariable-basic1 
10 threads ready to race...
thread 1
thread 0
thread 2
thread 3
thread 4
thread 5
thread 6
thread 7
thread 8
thread 9
 

Well, after the conditional variables have a basic understanding of, let's look at each member function std :: condition_variable of.

std :: condition_variable constructor

default (1)
condition_variable();
copy [deleted] (2)
condition_variable (const condition_variable&) = delete;

std :: condition_variable copy constructor is disabled, only provide a default constructor.

std :: condition_variable :: wait () Introduction

unconditional (1)
void wait (unique_lock<mutex>& lck);
predicate (2)
template <class Predicate>
  void wait (unique_lock<mutex>& lck, Predicate pred);

std :: condition_variable provides two wait () function. After the current thread calls the wait () is blocked (at this time the current thread should get a lock (mutex), it may assume get the lock lck), until some other thread calls notify_ * wake of the current thread.

When the thread is blocked, this function will automatically call  lck.unlock() 释放锁,使得其他被阻塞在锁竞争上的线程得以继续执行。In addition, once the current thread to be notified (notified, usually some other thread calls notify_ * wake up the current thread), wait () function is invoked automatically lck.lock (), so that the same state is called lck and wait function.

In the second case (that is, set up a Predicate), only if pred conditions will block the current thread calls the wait is false (), and only when pred after receiving notice other thread will be unblocked to true . Therefore, the second case is similar to the following code:

while (!pred()) wait(lck);

Consider the following example ( Reference ):

 
#include <iostream>                // std::cout
#include <thread>                // std::thread, std::this_thread::yield
#include <mutex>                // std::mutex, std::unique_lock
#include <condition_variable>    // std::condition_variable

std::mutex mtx;
std::condition_variable cv;

int cargo = 0;
bool shipment_available()
{
    return cargo != 0;
}

// 消费者线程.
void consume(int n)
{
    for (int i = 0; i < n; ++i) {
        std::unique_lock <std::mutex> lck(mtx);
        cv.wait(lck, shipment_available);
        std::cout << cargo << '\n';
        cargo = 0;
    }
}

main int () 
{ 
    STD :: Thread consumer_thread (Consume, 10);. consumer thread // 

    // producer thread is the main thread, the production of 10 items. 
    for (int I = 0; I <10; I ++ ) { 
        the while (shipment_available ()) 
            STD :: :: this_thread the yield (); 
        STD unique_lock is :: <STD :: the mutex> LCK (MTX); 
        Cargo = I +. 1; 
        cv.notify_one (); 
    } 

    consumer_thread.join ( ); 

    return 0; 
}
 

Program execution results are as follows:

 
concurrency ) ./ConditionVariable-wait 
1
2
3
4
5
6
7
8
9
10
 

std::condition_variable::wait_for() 介绍

unconditional (1)
template <class Rep, class Period>
  cv_status wait_for (unique_lock<mutex>& lck,
                      const chrono::duration<Rep,Period>& rel_time);
predicate (2)
template <class Rep, class Period, class Predicate>
       bool wait_for (unique_lock<mutex>& lck,
                      const chrono::duration<Rep,Period>& rel_time, Predicate pred);

And  :: condition_variable :: wait () std  similar, but wait_for can specify a time period before the current thread rel_time timeout period specified or notified, the thread will be blocked state. Once out or has been notified, thread, wait_for return, the rest of the process steps and wait () is similar.

In addition, heavy-duty version of wait_for ( predicte (2) ) The last parameter represents the prediction pred conditions wait_for only if pred conditions will block the current thread calls the wait is false (), and after receiving the notice of other threads pred is true only if the will is unblocked, and thus corresponds to the following code:

return wait_until (lck, chrono::steady_clock::now() + rel_time, std::move(pred));

Consider the following example ( reference ), the following example, the main thread wait for the thread to enter a value th, th and the value received from the terminal thread printed, prior to receiving the value th thread, the main thread has to wait, for each one second timeout once and print a ".":

 
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <chrono>             // std::chrono::seconds
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status

std::condition_variable cv;

int value;

void do_read_value()
{
    std::cin >> value;
    cv.notify_one();
}

int main ()
{
    std::cout << "Please, enter an integer (I'll be printing dots): \n";
    std::thread th(do_read_value);

    std::mutex mtx;
    std::unique_lock<std::mutex> lck(mtx);
    while (cv.wait_for(lck,std::chrono::seconds(1)) == std::cv_status::timeout) {
        std::cout << '.';
        std::cout.flush();
    }

    std::cout << "You entered: " << value << '\n';

    th.join();
    return 0;
}
 

std::condition_variable::wait_until 介绍

unconditional (1)
template <class Clock, class Duration>
  cv_status wait_until (unique_lock<mutex>& lck,
                        const chrono::time_point<Clock,Duration>& abs_time);
predicate (2)
template <class Clock, class Duration, class Predicate>
       bool wait_until (unique_lock<mutex>& lck,
                        const chrono::time_point<Clock,Duration>& abs_time,
                        Predicate pred);

And  std :: condition_variable :: wait_for  similar, but wait_until can specify a point in time before the current thread is notified or the specified time point abs_time timeout, the thread will be blocked state. Once out or has been notified, thread, wait_until return, the rest of the process steps and wait_until () is similar.

In addition, heavy-duty version of wait_until ( predicte (2) ) The last parameter represents the prediction pred conditions wait_until only if pred conditions will block the current thread calls the wait is false (), and after receiving the notice of other threads pred is true only if the will is unblocked, and thus corresponds to the following code:

while (!pred())
  if ( wait_until(lck,abs_time) == cv_status::timeout)
    return pred();
return true;

std::condition_variable::notify_one() 介绍

Wake of a wait (wait) thread. If you do not wait for the current thread, the function does nothing, if there are multiple threads waiting, then wake up a thread is uncertain (unspecified).

See the following Example ( Reference ):

 
#include <iostream>                // std::cout
#include <thread>                // std::thread
#include <mutex>                // std::mutex, std::unique_lock
#include <condition_variable>    // std::condition_variable

std::mutex mtx;
std::condition_variable cv;

int cargo = 0; // shared value by producers and consumers

void consumer()
{
    std::unique_lock < std::mutex > lck(mtx);
    while (cargo == 0)
        cv.wait(lck);
    std::cout << cargo << '\n';
    cargo = 0;
}

void producer(int id)
{
    std::unique_lock < std::mutex > lck(mtx);
    cargo = id;
    cv.notify_one();
}

int main()
{
    std::thread consumers[10], producers[10];

    // spawn 10 consumers and 10 producers:
    for (int i = 0; i < 10; ++i) {
        consumers[i] = std::thread(consumer);
        producers[i] = std::thread(producer, i + 1);
    }

    // join them back:
    for (int i = 0; i < 10; ++i) {
        producers[i].join();
        consumers[i].join();
    }

    return 0;
}
 

std::condition_variable::notify_all() 介绍

Wake up all the wait (wait) thread. If there is no waiting thread, the function does nothing. Consider the following example:

 
#include <iostream> // std :: cout 
#include <the Thread> // std :: the Thread 
#include <mutex> // std :: mutex, std :: unique_lock 
#include <condition_variable> // std :: condition_variable 

std :: mutex mtx;. // global mutex 
std :: condition_variable cv;. // global variable conditions 
bool ready = false; // global flag. 

void do_print_id (int ID) 
{ 
    STD unique_lock is :: <STD :: mutex> LCK (mtx); 
    the while (! READY) // If the flag is not true, then wait ... 
        cv.wait (LCK); // current thread is blocked, when the global flag becomes true, 
    / / thread wakes up, printing continues down the thread number id. 
    STD :: COUT << "thread" id << << '\ n-'; 
} 

void Go () 
{ 
    STD unique_lock is :: <std::mutex> lck(mtx);
    ready = true; // 设置全局标志位为 true.
    cv.notify_all(); // 唤醒所有线程.
}

int main()
{
    std::thread threads[10];
    // spawn 10 threads:
    for (int i = 0; i < 10; ++i)
        threads[i] = std::thread(do_print_id, i);

    std::cout << "10 threads ready to race...\n";
    go(); // go!

  for (auto & th:threads)
        th.join();

    return 0;
}
 

 std :: condition_variable_any Introduction

And std ::condition_variable similar, but the wait std :: condition_variable_any lockable function can accept any parameters, and std :: condition_variable only accept std :: unique_lock <std :: mutex> type of parameters, in addition, and almost std :: condition_variable exactly the same.

std :: cv_status Enumerated Type Description

cv_status::no_timeout wait_for or wait_until not timed out, that is a time specified thread received a notification.
cv_status::timeout wait_for or wait_until timeout.

std::notify_all_at_thread_exit

Function prototype is:

void notify_all_at_thread_exit (condition_variable& cond, unique_lock<mutex> lck);

When the function is called thread exits, all in  cond  on condition variable waiting threads you will be notified. See the following Example ( Reference ):

 
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void print_id (int id) {
  std::unique_lock<std::mutex> lck(mtx);
  while (!ready) cv.wait(lck);
  // ...
  std::cout << "thread " << id << '\n';
}

void go() {
  std::unique_lock<std::mutex> lck(mtx);
  std::notify_all_at_thread_exit(cv,std::move(lck));
  ready = true;
}

int main ()
{
  std::thread threads[10];
  // spawn 10 threads:
  for (int i=0; i<10; ++i)
    threads[i] = std::thread(print_id,i);
  std::cout << "10 threads ready to race...\n";

  std::thread(go).detach();   // go!

  for (auto& th : threads) th.join();

  return 0;
}
 

 

Well, so far, <condition_variable> two conditions header file class variables (std :: condition_variable and std :: condition_variable_any), enumerated type (std :: cv_status), and an auxiliary function (std :: notify_all_at_thread_exit ( )) have been introduced over. From the beginning of the next chapter I will gradually began to introduce <atomic> header file contents, the subsequent article will introduce C ++ 11 memory model, involving some of the underlying content a little, I hope we can maintain interest, completion of C ++ 11 concurrent programming, if you find errors in this article, please give me feedback ;-).

Front three stresses " C ++ 11 concurrency guide two (std :: thread Detailed) ", " C ++ 11 concurrency guide three (std :: mutex Detailed) " introduced the std :: thread, std :: mutex, std :: future and other related content, I believe readers of multi-threaded programming in C ++ 11 has a basic understanding, this article will introduce the C ++ 11 standard <condition_variable> header file inside the class and related functions.

<Condition_variable> main header contains the classes and functions relating to the condition variable. Related classes include std :: condition_variable and std :: condition_variable_any, there are enumerated type std :: cv_status. Also included are a function of std :: notify_all_at_thread_exit (), below are brief or more types.

std :: condition_variable class presentation

std :: condition_variable condition variable is defined more about the condition variable reference Wikipedia . Use Pthread library pthread_cond under Linux _ * () function provides information on the condition variable functions, Windows reference is  the MSDN .

When a wait function std :: condition_variable object is called, it uses std :: unique_lock to lock the current thread (via std :: mutex). The current thread will always be blocked until another thread calls a notification function on the same std :: condition_variable object to awaken the current thread.

std :: condition_variable regularly use std :: unique_lock <std :: mutex> wait, if necessary using additional lockable type, may be used std :: condition_variable_any classes will be mentioned later herein, std :: condition_variable_any usage.

First we look at a simple example

 
#include <iostream> // std :: cout 
#include <the Thread> // std :: the Thread 
#include <mutex> // std :: mutex, std :: unique_lock 
#include <condition_variable> // std :: condition_variable 

std :: mutex mtx;. // global mutex 
std :: condition_variable cv;. // global variable conditions 
bool ready = false; // global flag. 

void do_print_id (int ID) 
{ 
    STD unique_lock is :: <STD :: mutex> LCK (mtx); 
    the while (! READY) // If the flag is not true, then wait ... 
        cv.wait (LCK); // current thread is blocked, when the global flag becomes true, 
    / / thread wakes up, printing continues down the thread number id. 
    STD :: COUT << "thread" id << << '\ n-'; 
} 

void Go () 
{ 
    STD unique_lock is :: <std::mutex> lck(mtx);
    ready = true; // 设置全局标志位为 true.
    cv.notify_all(); // 唤醒所有线程.
}

int main()
{
    std::thread threads[10];
    // spawn 10 threads:
    for (int i = 0; i < 10; ++i)
        threads[i] = std::thread(do_print_id, i);

    std::cout << "10 threads ready to race...\n";
    go(); // go!

  for (auto & th:threads)
        th.join();

    return 0;
}
 

Execution results are as follows:

 
concurrency ) ./ConditionVariable-basic1 
10 threads ready to race...
thread 1
thread 0
thread 2
thread 3
thread 4
thread 5
thread 6
thread 7
thread 8
thread 9
 

Well, after the conditional variables have a basic understanding of, let's look at each member function std :: condition_variable of.

std :: condition_variable constructor

default (1)
condition_variable();
copy [deleted] (2)
condition_variable (const condition_variable&) = delete;

std :: condition_variable copy constructor is disabled, only provide a default constructor.

std :: condition_variable :: wait () Introduction

unconditional (1)
void wait (unique_lock<mutex>& lck);
predicate (2)
template <class Predicate>
  void wait (unique_lock<mutex>& lck, Predicate pred);

std :: condition_variable provides two wait () function. After the current thread calls the wait () is blocked (at this time the current thread should get a lock (mutex), it may assume get the lock lck), until some other thread calls notify_ * wake of the current thread.

When the thread is blocked, this function will automatically call  lck.unlock() 释放锁,使得其他被阻塞在锁竞争上的线程得以继续执行。In addition, once the current thread to be notified (notified, usually some other thread calls notify_ * wake up the current thread), wait () function is invoked automatically lck.lock (), so that the same state is called lck and wait function.

In the second case (that is, set up a Predicate), only if pred conditions will block the current thread calls the wait is false (), and only when pred after receiving notice other thread will be unblocked to true . Therefore, the second case is similar to the following code:

while (!pred()) wait(lck);

Consider the following example ( Reference ):

 
#include <iostream>                // std::cout
#include <thread>                // std::thread, std::this_thread::yield
#include <mutex>                // std::mutex, std::unique_lock
#include <condition_variable>    // std::condition_variable

std::mutex mtx;
std::condition_variable cv;

int cargo = 0;
bool shipment_available()
{
    return cargo != 0;
}

// 消费者线程.
void consume(int n)
{
    for (int i = 0; i < n; ++i) {
        std::unique_lock <std::mutex> lck(mtx);
        cv.wait(lck, shipment_available);
        std::cout << cargo << '\n';
        cargo = 0;
    }
}

main int () 
{ 
    STD :: Thread consumer_thread (Consume, 10);. consumer thread // 

    // producer thread is the main thread, the production of 10 items. 
    for (int I = 0; I <10; I ++ ) { 
        the while (shipment_available ()) 
            STD :: :: this_thread the yield (); 
        STD unique_lock is :: <STD :: the mutex> LCK (MTX); 
        Cargo = I +. 1; 
        cv.notify_one (); 
    } 

    consumer_thread.join ( ); 

    return 0; 
}
 

Program execution results are as follows:

 
concurrency ) ./ConditionVariable-wait 
1
2
3
4
5
6
7
8
9
10
 

std::condition_variable::wait_for() 介绍

unconditional (1)
template <class Rep, class Period>
  cv_status wait_for (unique_lock<mutex>& lck,
                      const chrono::duration<Rep,Period>& rel_time);
predicate (2)
template <class Rep, class Period, class Predicate>
       bool wait_for (unique_lock<mutex>& lck,
                      const chrono::duration<Rep,Period>& rel_time, Predicate pred);

And  :: condition_variable :: wait () std  similar, but wait_for can specify a time period before the current thread rel_time timeout period specified or notified, the thread will be blocked state. Once out or has been notified, thread, wait_for return, the rest of the process steps and wait () is similar.

In addition, heavy-duty version of wait_for ( predicte (2) ) The last parameter represents the prediction pred conditions wait_for only if pred conditions will block the current thread calls the wait is false (), and after receiving the notice of other threads pred is true only if the will is unblocked, and thus corresponds to the following code:

return wait_until (lck, chrono::steady_clock::now() + rel_time, std::move(pred));

Consider the following example ( reference ), the following example, the main thread wait for the thread to enter a value th, th and the value received from the terminal thread printed, prior to receiving the value th thread, the main thread has to wait, for each one second timeout once and print a ".":

 
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <chrono>             // std::chrono::seconds
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status

std::condition_variable cv;

int value;

void do_read_value()
{
    std::cin >> value;
    cv.notify_one();
}

int main ()
{
    std::cout << "Please, enter an integer (I'll be printing dots): \n";
    std::thread th(do_read_value);

    std::mutex mtx;
    std::unique_lock<std::mutex> lck(mtx);
    while (cv.wait_for(lck,std::chrono::seconds(1)) == std::cv_status::timeout) {
        std::cout << '.';
        std::cout.flush();
    }

    std::cout << "You entered: " << value << '\n';

    th.join();
    return 0;
}
 

std::condition_variable::wait_until 介绍

unconditional (1)
template <class Clock, class Duration>
  cv_status wait_until (unique_lock<mutex>& lck,
                        const chrono::time_point<Clock,Duration>& abs_time);
predicate (2)
template <class Clock, class Duration, class Predicate>
       bool wait_until (unique_lock<mutex>& lck,
                        const chrono::time_point<Clock,Duration>& abs_time,
                        Predicate pred);

And  std :: condition_variable :: wait_for  similar, but wait_until can specify a point in time before the current thread is notified or the specified time point abs_time timeout, the thread will be blocked state. Once out or has been notified, thread, wait_until return, the rest of the process steps and wait_until () is similar.

In addition, heavy-duty version of wait_until ( predicte (2) ) The last parameter represents the prediction pred conditions wait_until only if pred conditions will block the current thread calls the wait is false (), and after receiving the notice of other threads pred is true only if the will is unblocked, and thus corresponds to the following code:

while (!pred())
  if ( wait_until(lck,abs_time) == cv_status::timeout)
    return pred();
return true;

std::condition_variable::notify_one() 介绍

Wake of a wait (wait) thread. If you do not wait for the current thread, the function does nothing, if there are multiple threads waiting, then wake up a thread is uncertain (unspecified).

See the following Example ( Reference ):

 
#include <iostream>                // std::cout
#include <thread>                // std::thread
#include <mutex>                // std::mutex, std::unique_lock
#include <condition_variable>    // std::condition_variable

std::mutex mtx;
std::condition_variable cv;

int cargo = 0; // shared value by producers and consumers

void consumer()
{
    std::unique_lock < std::mutex > lck(mtx);
    while (cargo == 0)
        cv.wait(lck);
    std::cout << cargo << '\n';
    cargo = 0;
}

void producer(int id)
{
    std::unique_lock < std::mutex > lck(mtx);
    cargo = id;
    cv.notify_one();
}

int main()
{
    std::thread consumers[10], producers[10];

    // spawn 10 consumers and 10 producers:
    for (int i = 0; i < 10; ++i) {
        consumers[i] = std::thread(consumer);
        producers[i] = std::thread(producer, i + 1);
    }

    // join them back:
    for (int i = 0; i < 10; ++i) {
        producers[i].join();
        consumers[i].join();
    }

    return 0;
}
 

std::condition_variable::notify_all() 介绍

Wake up all the wait (wait) thread. If there is no waiting thread, the function does nothing. Consider the following example:

 
#include <iostream> // std :: cout 
#include <the Thread> // std :: the Thread 
#include <mutex> // std :: mutex, std :: unique_lock 
#include <condition_variable> // std :: condition_variable 

std :: mutex mtx;. // global mutex 
std :: condition_variable cv;. // global variable conditions 
bool ready = false; // global flag. 

void do_print_id (int ID) 
{ 
    STD unique_lock is :: <STD :: mutex> LCK (mtx); 
    the while (! READY) // If the flag is not true, then wait ... 
        cv.wait (LCK); // current thread is blocked, when the global flag becomes true, 
    / / thread wakes up, printing continues down the thread number id. 
    STD :: COUT << "thread" id << << '\ n-'; 
} 

void Go () 
{ 
    STD unique_lock is :: <std::mutex> lck(mtx);
    ready = true; // 设置全局标志位为 true.
    cv.notify_all(); // 唤醒所有线程.
}

int main()
{
    std::thread threads[10];
    // spawn 10 threads:
    for (int i = 0; i < 10; ++i)
        threads[i] = std::thread(do_print_id, i);

    std::cout << "10 threads ready to race...\n";
    go(); // go!

  for (auto & th:threads)
        th.join();

    return 0;
}
 

 std :: condition_variable_any Introduction

And std ::condition_variable similar, but the wait std :: condition_variable_any lockable function can accept any parameters, and std :: condition_variable only accept std :: unique_lock <std :: mutex> type of parameters, in addition, and almost std :: condition_variable exactly the same.

std :: cv_status Enumerated Type Description

cv_status::no_timeout wait_for or wait_until not timed out, that is a time specified thread received a notification.
cv_status::timeout wait_for 或者 wait_until 超时。

std::notify_all_at_thread_exit

函数原型为:

void notify_all_at_thread_exit (condition_variable& cond, unique_lock<mutex> lck);

当调用该函数的线程退出时,所有在 cond 条件变量上等待的线程都会收到通知。请看下例(参考):

 
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void print_id (int id) {
  std::unique_lock<std::mutex> lck(mtx);
  while (!ready) cv.wait(lck);
  // ...
  std::cout << "thread " << id << '\n';
}

void go() {
  std::unique_lock<std::mutex> lck(mtx);
  std::notify_all_at_thread_exit(cv,std::move(lck));
  ready = true;
}

int main ()
{
  std::thread threads[10];
  // spawn 10 threads:
  for (int i=0; i<10; ++i)
    threads[i] = std::thread(print_id,i);
  std::cout << "10 threads ready to race...\n";

  std::thread(go).detach();   // go!

  for (auto& th : threads) th.join();

  return 0;
}
 

 

好了,到此为止,<condition_variable> 头文件中的两个条件变量类(std::condition_variable 和 std::condition_variable_any)、枚举类型(std::cv_status)、以及辅助函数(std::notify_all_at_thread_exit())都已经介绍完了。从下一章开始我会逐步开始介绍 <atomic> 头文件中的内容,后续的文章还会介绍 C++11 的内存模型,涉及内容稍微底层一些,希望大家能够保持兴趣,学完 C++11 并发编程,如果你发现本文中的错误,也请给我反馈 ;-)。

Guess you like

Origin www.cnblogs.com/leijiangtao/p/12046288.html