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 * Author: Moyang Wang 36 */ 37 38#include <pthread.h> 39 40#include <cstdlib> 41#include <iostream> 42#include <mutex> 43#include <vector> 44 45//------------------------------------------------------------------------ 46// Test pthread_cond 47//------------------------------------------------------------------------ 48// The master thread creates N threads, each of which waits on a 49// condition variable of a signal to start. The master thread then set 50// the signal and notifies all other threads to begin. 51 52#define MAX_N_WORKER_THREADS 10 53 54pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 55pthread_cond_t cv = PTHREAD_COND_INITIALIZER; 56 57bool ready = false; 58 59void* print_id( void* arg_vptr ) 60{ 61 pthread_mutex_lock( &mutex ); 62 long id = (long)arg_vptr; 63 64 while (!ready) { 65 pthread_cond_wait( &cv, &mutex ); 66 } 67 // ... 68 std::cout << "thread " << id << '\n'; 69 70 pthread_mutex_unlock( &mutex ); 71 72 return nullptr; 73} 74 75void go() 76{ 77 pthread_mutex_lock( &mutex ); 78 ready = true; 79 pthread_cond_broadcast( &cv ); 80 pthread_mutex_unlock( &mutex ); 81} 82 83int main( int argc, char* argv[] ) 84{ 85 size_t n_worker_threads = 0; 86 87 std::vector< pthread_t > threads( MAX_N_WORKER_THREADS ); 88 89 int ret = 0; 90 for ( size_t i = 0; i < MAX_N_WORKER_THREADS; i++ ){ 91 ret = pthread_create( &threads[i], nullptr, print_id, (void*)i ); 92 if (ret != 0) { 93 break; 94 } 95 n_worker_threads++; 96 } 97 98 std::cout << n_worker_threads << " threads ready to race...\n"; 99 100 go(); 101 102 for ( size_t i = 1; i < n_worker_threads; i++ ) { 103 pthread_join( threads[i], nullptr ); 104 } 105 106 if (n_worker_threads < 1) { 107 return EXIT_FAILURE; 108 } 109 110 return EXIT_SUCCESS; 111} 112