1/* 2 * Copyright (c) 2018, Cornell University 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or 6 * without modification, are permitted provided that the following 7 * conditions are met: 8 * 9 * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following 14 * disclaimer in the documentation and/or other materials provided 15 * with the distribution. 16 * 17 * Neither the name of Cornell University nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 22 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 23 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 26 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 29 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 * 35 * Authors: Moyang Wang 36 */ 37 38#include <condition_variable> 39#include <iostream> 40#include <mutex> 41#include <thread> 42#include <vector> 43 44//------------------------------------------------------------------------ 45// Test std::condition_variable 46//------------------------------------------------------------------------ 47// The master thread creates N threads, each of which waits on a 48// condition variable of a signal to start. The master thread then set 49// the signal and notifies all other threads to begin. 50 51#define MAX_N_WORKER_THREADS 10 52 53std::mutex mtx; 54std::condition_variable cv; 55bool ready = false; 56 57void print_id( size_t id ) 58{ 59 std::unique_lock<std::mutex> lck(mtx); 60 while (!ready) 61 cv.wait(lck); 62 // ... 63 std::cout << "thread " << id << '\n'; 64} 65 66void go() 67{ 68 std::unique_lock<std::mutex> lck(mtx); 69 ready = true; 70 cv.notify_all(); 71} 72 73int main( int argc, char* argv[] ) 74{ 75 size_t n_worker_threads = 0; 76 77 std::vector< std::thread > threads; 78 79 for ( size_t i = 0; i < MAX_N_WORKER_THREADS; i++ ) { 80 try { 81 threads.push_back( std::thread( print_id, i ) ); 82 } catch ( const std::system_error& err ) { 83 break; 84 } 85 n_worker_threads++; 86 } 87 88 std::cout << n_worker_threads << " threads ready to race...\n"; 89 go(); // go! 90 91 for (int i = 0; i < n_worker_threads; ++i) { 92 threads[i].join(); 93 } 94 95 // if there is no timeout (i.e., threads are all waken up properly, this 96 // test always succeeds) 97 return EXIT_SUCCESS; 98} 99