123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- // Copyright (C) 2012 Vicente J. Botet Escriba
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- #include <iostream>
- #include <boost/thread/mutex.hpp>
- #include <boost/thread/shared_mutex.hpp>
- #include <boost/thread/lock_algorithms.hpp>
- #include <boost/thread/thread_only.hpp>
- #if defined BOOST_THREAD_DONT_USE_CHRONO
- #include <boost/chrono/chrono_io.hpp>
- #endif
- #include <cassert>
- #include <vector>
- #define EXCLUSIVE 1
- #define SHARED 2
- #define MODE SHARED
- class A
- {
- #if MODE == EXCLUSIVE
- typedef boost::mutex mutex_type;
- #elif MODE == SHARED
- typedef boost::shared_mutex mutex_type;
- #else
- #error MODE not set
- #endif
- typedef std::vector<double> C;
- mutable mutex_type mut_;
- C data_;
- public:
- A() : data_(10000000) {}
- A(const A& a);
- A& operator=(const A& a);
- void compute(const A& x, const A& y);
- };
- A::A(const A& a)
- {
- #if MODE == EXCLUSIVE
- boost::unique_lock<mutex_type> lk(a.mut_);
- #elif MODE == SHARED
- boost::shared_lock<mutex_type> lk(a.mut_);
- #else
- #error MODE not set
- #endif
- data_ = a.data_;
- }
- A&
- A::operator=(const A& a)
- {
- if (this != &a)
- {
- boost::unique_lock<mutex_type> lk1(mut_, boost::defer_lock);
- #if MODE == EXCLUSIVE
- boost::unique_lock<mutex_type> lk2(a.mut_, boost::defer_lock);
- #elif MODE == SHARED
- boost::shared_lock<mutex_type> lk2(a.mut_, boost::defer_lock);
- #else
- #error MODE not set
- #endif
- boost::lock(lk1, lk2);
- data_ = a.data_;
- }
- return *this;
- }
- void
- A::compute(const A& x, const A& y)
- {
- boost::unique_lock<mutex_type> lk1(mut_, boost::defer_lock);
- #if MODE == EXCLUSIVE
- boost::unique_lock<mutex_type> lk2(x.mut_, boost::defer_lock);
- boost::unique_lock<mutex_type> lk3(y.mut_, boost::defer_lock);
- #elif MODE == SHARED
- boost::shared_lock<mutex_type> lk2(x.mut_, boost::defer_lock);
- boost::shared_lock<mutex_type> lk3(y.mut_, boost::defer_lock);
- #else
- #error MODE not set
- #endif
- boost::lock(lk1, lk2, lk3);
- assert(data_.size() == x.data_.size());
- assert(data_.size() == y.data_.size());
- for (unsigned i = 0; i < data_.size(); ++i)
- data_[i] = (x.data_[i] + y.data_[i]) / 2;
- }
- A a1;
- A a2;
- void test_s()
- {
- A la3 = a1;
- for (int i = 0; i < 150; ++i)
- {
- la3.compute(a1, a2);
- }
- }
- void test_w()
- {
- A la3 = a1;
- for (int i = 0; i < 10; ++i)
- {
- la3.compute(a1, a2);
- a1 = la3;
- a2 = la3;
- #if defined BOOST_THREAD_DONT_USE_CHRONO
- boost::this_thread::sleep_for(boost::chrono::seconds(1));
- #endif
- }
- }
- int main()
- {
- #if defined BOOST_THREAD_DONT_USE_CHRONO
- typedef boost::chrono::high_resolution_clock Clock;
- typedef boost::chrono::duration<double> sec;
- Clock::time_point t0 = Clock::now();
- #endif
- std::vector<boost::thread*> v;
- boost::thread thw(test_w);
- v.push_back(&thw);
- boost::thread thr0(test_w);
- v.push_back(&thr0);
- boost::thread thr1(test_w);
- v.push_back(&thr1);
- boost::thread thr2(test_w);
- v.push_back(&thr2);
- boost::thread thr3(test_w);
- v.push_back(&thr3);
- for (std::size_t i = 0; i < v.size(); ++i)
- v[i]->join();
- #if defined BOOST_THREAD_DONT_USE_CHRONO
- Clock::time_point t1 = Clock::now();
- std::cout << sec(t1-t0) << '\n';
- #endif
- return 0;
- }
|