|
barrier_sync.cc
// // $Id: barrier_sync.cc,v 1.5 2003/10/30 15:05:12 cholm Exp $ // // Test of threads - C %example ex9.c // Copyright (C) 2002 Christian Holm Christensen <cholm@nbi.dk> // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation; either version 2.1 // of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA // 02111-1307 USA // #ifndef OPTION_HH #include "option.hh" #endif #ifndef THREADMM_thread #include <threadmm/thread.hh> #endif #ifndef THREADMM_barrier #include <threadmm/barrier.hh> #endif #ifndef THREADMM_mutex #include <threadmm/mutex.hh> #endif #ifndef THREADMM_lock_guard #include <threadmm/lock_guard.hh> #endif #ifndef __TYPEINFO__ #include <typeinfo> #endif #if defined(HAVE_POSIX_SLEEP) # ifndef _UNISTD_H # include <unistd.h> # endif # define SLEEP(x) sleep(x) #elif defined(HAVE_WIN32_SLEEP) # ifndef _WINDOWS_H # include <windows.h> # endif # define SLEEP(x) Sleep(x*1000) #endif #ifndef __CSTDIO__ # include <cstdio> #endif using namespace std; namespace example { class rendevoue : public threadmm::thread { private: threadmm::barrier* _barrier; int _iterations; static threadmm::thread* _last_serial; static int _line; static threadmm::mutex _mutex; public: rendevoue(threadmm::barrier* b, int iterations) : _barrier(b), _iterations(iterations) {} void print(bool serial) { threadmm::lock_guard<threadmm::mutex> g(_mutex, true); cout << setw(4) << dec << _line++ << ": " << (!serial ? "non-" : "") << "serial thread " << hex << this << endl; if (serial) _last_serial = this; } void last() { threadmm::lock_guard<threadmm::mutex> g(_mutex, true); cout << setw(4) << dec << _line++ << ": last serial thread " << hex << this << " terminating process" << endl; // terminate the process. ::exit(0); } void* operator()() { // Without this line, the program hangs! cout << "Staring thread " << hex << this << endl; SLEEP(1); // iterate until we get the last serial %thread to terminate. for (int i = 0; i < _iterations; i++) { bool serial = _barrier->wait(); print(serial); // print(_barrier->wait()); } // If this is the last, let it terminate if (*_last_serial == *this) last(); exit(0); return 0; } }; threadmm::thread* rendevoue::_last_serial = 0; threadmm::mutex rendevoue::_mutex; int rendevoue::_line = 0; class barrier_sync { public: barrier_sync() {} int run() { // Sync I/O ios::sync_with_stdio(true); cout.setf(ios::unitbuf); cerr.setf(ios::unitbuf); try { threadmm::barrier b(11); for (int i = 0; i < 10; i++) { std::cout << "Creating thread # " << i << std::endl; rendevoue* r = new rendevoue(&b, 500); r->run(); } rendevoue r(&b, 500); r(); } catch(exception& e) { cerr << e.what() << endl; // if (typeid(e) == typeid(threadmm::not_supported)) // return 0; return 1; } return 0; } }; } //_______________________________________________________________________ int main(int argc, char** argv) { if (!example::options(argc, argv)) return 0; example::barrier_sync exa; return exa.run(); } //_______________________________________________________________________ // // EOF // Last update Tue Nov 9 12:40:50 2004 Christian Holm Created by DoxyGen 1.3.9.1 |