// 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)#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN#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>#include <vector>#if defined BOOST_THREAD_USES_CHRONO#include <boost/chrono/chrono_io.hpp>enum {reading, writing};int state = reading;#if 1boost::mutex&cout_mut(){static boost::mutex m;return m;}voidprint(const char* tag, unsigned count, char ch){boost::lock_guard<boost::mutex> _(cout_mut());std::cout << tag << count << ch;}#elif 0boost::recursive_mutex&cout_mut(){static boost::recursive_mutex m;return m;}void print() {}template <class A0, class ...Args>voidprint(const A0& a0, const Args& ...args){boost::lock_guard<boost::recursive_mutex> _(cout_mut());std::cout << a0;print(args...);}#elsetemplate <class A0, class A1, class A2>voidprint(const A0&, const A1& a1, const A2&){assert(a1 > 10000);}#endifnamespace S{boost::shared_mutex mut;void reader(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){mut.lock_shared();assert(state == reading);++count;mut.unlock_shared();}print("reader = ", count, '\n');}void writer(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){mut.lock();state = writing;assert(state == writing);state = reading;++count;mut.unlock();}print("writer = ", count, '\n');}void try_reader(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock_shared()){assert(state == reading);++count;mut.unlock_shared();}}print("try_reader = ", count, '\n');}void try_writer(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock()){state = writing;assert(state == writing);state = reading;++count;mut.unlock();}}print("try_writer = ", count, '\n');}void try_for_reader(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock_shared_for(boost::chrono::microseconds(5))){assert(state == reading);++count;mut.unlock_shared();}}print("try_for_reader = ", count, '\n');}void try_for_writer(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock_for(boost::chrono::microseconds(5))){state = writing;assert(state == writing);state = reading;++count;mut.unlock();}}print("try_for_writer = ", count, '\n');}voidtest_shared_mutex(){std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;{boost::thread t1(reader);boost::thread t2(writer);boost::thread t3(reader);t1.join();t2.join();t3.join();}std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;{boost::thread t1(try_reader);boost::thread t2(try_writer);boost::thread t3(try_reader);t1.join();t2.join();t3.join();}std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;{boost::thread t1(try_for_reader);boost::thread t2(try_for_writer);boost::thread t3(try_for_reader);t1.join();t2.join();t3.join();}std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;}}namespace U{boost::upgrade_mutex mut;void reader(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){mut.lock_shared();assert(state == reading);++count;mut.unlock_shared();}print("reader = ", count, '\n');}void writer(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){mut.lock();state = writing;assert(state == writing);state = reading;++count;mut.unlock();}print("writer = ", count, '\n');}void try_reader(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock_shared()){assert(state == reading);++count;mut.unlock_shared();}}print("try_reader = ", count, '\n');}void try_writer(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock()){state = writing;assert(state == writing);state = reading;++count;mut.unlock();}}print("try_writer = ", count, '\n');}void try_for_reader(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock_shared_for(boost::chrono::microseconds(5))){assert(state == reading);++count;mut.unlock_shared();}}print("try_for_reader = ", count, '\n');}void try_for_writer(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock_for(boost::chrono::microseconds(5))){state = writing;assert(state == writing);state = reading;++count;mut.unlock();}}print("try_for_writer = ", count, '\n');}void upgradable(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){mut.lock_upgrade();assert(state == reading);++count;mut.unlock_upgrade();}print("upgradable = ", count, '\n');}void try_upgradable(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock_upgrade()){assert(state == reading);++count;mut.unlock_upgrade();}}print("try_upgradable = ", count, '\n');}void try_for_upgradable(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock_upgrade_for(boost::chrono::microseconds(5))){assert(state == reading);++count;mut.unlock_upgrade();}}print("try_for_upgradable = ", count, '\n');}void clockwise(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){mut.lock_shared();assert(state == reading);if (mut.try_unlock_shared_and_lock()){state = writing;}else if (mut.try_unlock_shared_and_lock_upgrade()){assert(state == reading);mut.unlock_upgrade_and_lock();state = writing;}else{mut.unlock_shared();continue;}assert(state == writing);state = reading;mut.unlock_and_lock_upgrade();assert(state == reading);mut.unlock_upgrade_and_lock_shared();assert(state == reading);mut.unlock_shared();++count;}print("clockwise = ", count, '\n');}void counter_clockwise(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){mut.lock_upgrade();assert(state == reading);mut.unlock_upgrade_and_lock();assert(state == reading);state = writing;assert(state == writing);state = reading;mut.unlock_and_lock_shared();assert(state == reading);mut.unlock_shared();++count;}print("counter_clockwise = ", count, '\n');}void try_clockwise(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock_shared()){assert(state == reading);if (mut.try_unlock_shared_and_lock()){state = writing;}else if (mut.try_unlock_shared_and_lock_upgrade()){assert(state == reading);mut.unlock_upgrade_and_lock();state = writing;}else{mut.unlock_shared();continue;}assert(state == writing);state = reading;mut.unlock_and_lock_upgrade();assert(state == reading);mut.unlock_upgrade_and_lock_shared();assert(state == reading);mut.unlock_shared();++count;}}print("try_clockwise = ", count, '\n');}void try_for_clockwise(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock_shared_for(boost::chrono::microseconds(5))){assert(state == reading);if (mut.try_unlock_shared_and_lock_for(boost::chrono::microseconds(5))){state = writing;}else if (mut.try_unlock_shared_and_lock_upgrade_for(boost::chrono::microseconds(5))){assert(state == reading);mut.unlock_upgrade_and_lock();state = writing;}else{mut.unlock_shared();continue;}assert(state == writing);state = reading;mut.unlock_and_lock_upgrade();assert(state == reading);mut.unlock_upgrade_and_lock_shared();assert(state == reading);mut.unlock_shared();++count;}}print("try_for_clockwise = ", count, '\n');}void try_counter_clockwise(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock_upgrade()){assert(state == reading);if (mut.try_unlock_upgrade_and_lock()){assert(state == reading);state = writing;assert(state == writing);state = reading;mut.unlock_and_lock_shared();assert(state == reading);mut.unlock_shared();++count;}else{mut.unlock_upgrade();}}}print("try_counter_clockwise = ", count, '\n');}void try_for_counter_clockwise(){typedef boost::chrono::steady_clock Clock;unsigned count = 0;Clock::time_point until = Clock::now() + boost::chrono::seconds(3);while (Clock::now() < until){if (mut.try_lock_upgrade_for(boost::chrono::microseconds(5))){assert(state == reading);if (mut.try_unlock_upgrade_and_lock_for(boost::chrono::microseconds(5))){assert(state == reading);state = writing;assert(state == writing);state = reading;mut.unlock_and_lock_shared();assert(state == reading);mut.unlock_shared();++count;}else{mut.unlock_upgrade();}}}print("try_for_counter_clockwise = ", count, '\n');}voidtest_upgrade_mutex(){std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;{boost::thread t1(reader);boost::thread t2(writer);boost::thread t3(reader);t1.join();t2.join();t3.join();}std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;{boost::thread t1(try_reader);boost::thread t2(try_writer);boost::thread t3(try_reader);t1.join();t2.join();t3.join();}std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;{boost::thread t1(try_for_reader);boost::thread t2(try_for_writer);boost::thread t3(try_for_reader);t1.join();t2.join();t3.join();}std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;{boost::thread t1(reader);boost::thread t2(writer);boost::thread t3(upgradable);t1.join();t2.join();t3.join();}std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;{boost::thread t1(reader);boost::thread t2(writer);boost::thread t3(try_upgradable);t1.join();t2.join();t3.join();}std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;{boost::thread t1(reader);boost::thread t2(writer);boost::thread t3(try_for_upgradable);t1.join();t2.join();t3.join();}std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;{state = reading;boost::thread t1(clockwise);boost::thread t2(counter_clockwise);boost::thread t3(clockwise);boost::thread t4(counter_clockwise);t1.join();t2.join();t3.join();t4.join();}std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;{state = reading;boost::thread t1(try_clockwise);boost::thread t2(try_counter_clockwise);t1.join();t2.join();}std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;// {// state = reading;// boost::thread t1(try_for_clockwise);// boost::thread t2(try_for_counter_clockwise);// t1.join();// t2.join();// }// std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;}}namespace Assignment{class A{typedef boost::upgrade_mutex mutex_type;typedef boost::shared_lock<mutex_type> SharedLock;typedef boost::upgrade_lock<mutex_type> UpgradeLock;typedef boost::unique_lock<mutex_type> Lock;mutable mutex_type mut_;std::vector<double> data_;public:A(const A& a){SharedLock _(a.mut_);data_ = a.data_;}A& operator=(const A& a){if (this != &a){Lock this_lock(mut_, boost::defer_lock);SharedLock that_lock(a.mut_, boost::defer_lock);boost::lock(this_lock, that_lock);data_ = a.data_;}return *this;}void swap(A& a){Lock this_lock(mut_, boost::defer_lock);Lock that_lock(a.mut_, boost::defer_lock);boost::lock(this_lock, that_lock);data_.swap(a.data_);}void average(A& a){assert(data_.size() == a.data_.size());assert(this != &a);Lock this_lock(mut_, boost::defer_lock);UpgradeLock share_that_lock(a.mut_, boost::defer_lock);boost::lock(this_lock, share_that_lock);for (unsigned i = 0; i < data_.size(); ++i)data_[i] = (data_[i] + a.data_[i]) / 2;SharedLock share_this_lock(boost::move(this_lock));Lock that_lock(boost::move(share_that_lock));a.data_ = data_;}};} // Assignmentvoid temp(){using namespace boost;static upgrade_mutex mut;unique_lock<upgrade_mutex> ul(mut);shared_lock<upgrade_mutex> sl;sl = BOOST_THREAD_MAKE_RV_REF(shared_lock<upgrade_mutex>(boost::move(ul)));}int main(){std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;typedef boost::chrono::high_resolution_clock Clock;typedef boost::chrono::duration<double> sec;Clock::time_point t0 = Clock::now();std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;S::test_shared_mutex();std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;U::test_upgrade_mutex();std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;Clock::time_point t1 = Clock::now();std::cout << sec(t1 - t0) << '\n';return 0;}#else#error "This platform doesn't support Boost.Chrono"#endif
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。