112751Sqtt2@cornell.edu/* 212751Sqtt2@cornell.edu * Copyright (c) 2018, Cornell University 312751Sqtt2@cornell.edu * All rights reserved. 412751Sqtt2@cornell.edu * 512751Sqtt2@cornell.edu * Redistribution and use in source and binary forms, with or 612751Sqtt2@cornell.edu * without modification, are permitted provided that the following 712751Sqtt2@cornell.edu * conditions are met: 812751Sqtt2@cornell.edu * 912751Sqtt2@cornell.edu * Redistributions of source code must retain the above copyright 1012751Sqtt2@cornell.edu * notice, this list of conditions and the following disclaimer. 1112751Sqtt2@cornell.edu * 1212751Sqtt2@cornell.edu * Redistributions in binary form must reproduce the above 1312751Sqtt2@cornell.edu * copyright notice, this list of conditions and the following 1412751Sqtt2@cornell.edu * disclaimer in the documentation and/or other materials provided 1512751Sqtt2@cornell.edu * with the distribution. 1612751Sqtt2@cornell.edu * 1712751Sqtt2@cornell.edu * Neither the name of Cornell University nor the names of its 1812751Sqtt2@cornell.edu * contributors may be used to endorse or promote products derived 1912751Sqtt2@cornell.edu * from this software without specific prior written permission. 2012751Sqtt2@cornell.edu * 2112751Sqtt2@cornell.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 2212751Sqtt2@cornell.edu * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 2312751Sqtt2@cornell.edu * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 2412751Sqtt2@cornell.edu * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 2512751Sqtt2@cornell.edu * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 2612751Sqtt2@cornell.edu * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2712751Sqtt2@cornell.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2812751Sqtt2@cornell.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 2912751Sqtt2@cornell.edu * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 3012751Sqtt2@cornell.edu * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3112751Sqtt2@cornell.edu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 3212751Sqtt2@cornell.edu * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3312751Sqtt2@cornell.edu * POSSIBILITY OF SUCH DAMAGE. 3412751Sqtt2@cornell.edu * 3512751Sqtt2@cornell.edu * Authors: Moyang Wang 3612751Sqtt2@cornell.edu */ 3712751Sqtt2@cornell.edu 3812751Sqtt2@cornell.edu#include <condition_variable> 3912751Sqtt2@cornell.edu#include <iostream> 4012751Sqtt2@cornell.edu#include <mutex> 4112751Sqtt2@cornell.edu#include <thread> 4212751Sqtt2@cornell.edu#include <vector> 4312751Sqtt2@cornell.edu 4412751Sqtt2@cornell.edu//------------------------------------------------------------------------ 4512751Sqtt2@cornell.edu// Test std::condition_variable 4612751Sqtt2@cornell.edu//------------------------------------------------------------------------ 4712751Sqtt2@cornell.edu// The master thread creates N threads, each of which waits on a 4812751Sqtt2@cornell.edu// condition variable of a signal to start. The master thread then set 4912751Sqtt2@cornell.edu// the signal and notifies all other threads to begin. 5012751Sqtt2@cornell.edu 5112751Sqtt2@cornell.edu#define MAX_N_WORKER_THREADS 10 5212751Sqtt2@cornell.edu 5312751Sqtt2@cornell.edustd::mutex mtx; 5412751Sqtt2@cornell.edustd::condition_variable cv; 5512751Sqtt2@cornell.edubool ready = false; 5612751Sqtt2@cornell.edu 5712751Sqtt2@cornell.eduvoid print_id( size_t id ) 5812751Sqtt2@cornell.edu{ 5912751Sqtt2@cornell.edu std::unique_lock<std::mutex> lck(mtx); 6012751Sqtt2@cornell.edu while (!ready) 6112751Sqtt2@cornell.edu cv.wait(lck); 6212751Sqtt2@cornell.edu // ... 6312751Sqtt2@cornell.edu std::cout << "thread " << id << '\n'; 6412751Sqtt2@cornell.edu} 6512751Sqtt2@cornell.edu 6612751Sqtt2@cornell.eduvoid go() 6712751Sqtt2@cornell.edu{ 6812751Sqtt2@cornell.edu std::unique_lock<std::mutex> lck(mtx); 6912751Sqtt2@cornell.edu ready = true; 7012751Sqtt2@cornell.edu cv.notify_all(); 7112751Sqtt2@cornell.edu} 7212751Sqtt2@cornell.edu 7312751Sqtt2@cornell.eduint main( int argc, char* argv[] ) 7412751Sqtt2@cornell.edu{ 7512751Sqtt2@cornell.edu size_t n_worker_threads = 0; 7612751Sqtt2@cornell.edu 7712751Sqtt2@cornell.edu std::vector< std::thread > threads; 7812751Sqtt2@cornell.edu 7912751Sqtt2@cornell.edu for ( size_t i = 0; i < MAX_N_WORKER_THREADS; i++ ) { 8012751Sqtt2@cornell.edu try { 8112751Sqtt2@cornell.edu threads.push_back( std::thread( print_id, i ) ); 8212751Sqtt2@cornell.edu } catch ( const std::system_error& err ) { 8312751Sqtt2@cornell.edu break; 8412751Sqtt2@cornell.edu } 8512751Sqtt2@cornell.edu n_worker_threads++; 8612751Sqtt2@cornell.edu } 8712751Sqtt2@cornell.edu 8812751Sqtt2@cornell.edu std::cout << n_worker_threads << " threads ready to race...\n"; 8912751Sqtt2@cornell.edu go(); // go! 9012751Sqtt2@cornell.edu 9112751Sqtt2@cornell.edu for (int i = 0; i < n_worker_threads; ++i) { 9212751Sqtt2@cornell.edu threads[i].join(); 9312751Sqtt2@cornell.edu } 9412751Sqtt2@cornell.edu 9512751Sqtt2@cornell.edu // if there is no timeout (i.e., threads are all waken up properly, this 9612751Sqtt2@cornell.edu // test always succeeds) 9712751Sqtt2@cornell.edu return EXIT_SUCCESS; 9812751Sqtt2@cornell.edu} 99