You Only Need To Note This: only 1 single thread can acquire an upgrade_lock at one time.
others are very straightforward.
96 vote
|
1800 INFORMATION is more or less correct, but there are a few issues I wanted to correct. boost::shared_mutex _access;void reader(){ boost::shared_lock< boost::shared_mutex > lock(_access); // do work here, without anyone having exclusive access } void conditional_writer(){ boost::upgrade_lock< boost::shared_mutex > lock(_access); // do work here, without anyone having exclusive access if (something) { boost::upgrade_to_unique_lock< boost::shared_mutex > uniqueLock(lock); // do work here, but now you have exclusive access } // do more work here, without anyone having exclusive access } void unconditional_writer(){ boost::unique_lock< boost::shared_mutex > lock(_access); // do work here, with exclusive access } Also Note, unlike a shared_lock, only a single thread can acquire an upgrade_lock at one time, even when it isn't upgraded (which I thought was awkward when I ran into it). So, if all your readers are conditional writers, you need to find another solution. |
||
|
#pragma once #include "stdafx.h" #include <cstdlib> #include <iostream> #include <string> #include "boost/bind.hpp" #include "boost/smart_ptr.hpp" #include "boost/asio.hpp" #include "boost/thread/thread.hpp" #include "boost/date_time/posix_time/ptime.hpp" #include <boost/format.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/locks.hpp> #include <boost/algorithm/string/predicate.hpp> #include <boost/exception/diagnostic_information.hpp> #include <boost/exception_ptr.hpp> #include <boost/thread/shared_mutex.hpp> #include <boost/lexical_cast.hpp> typedef boost::shared_mutex Lock; typedef boost::unique_lock< Lock > WriteLock_uniq; typedef boost::upgrade_lock< Lock > WriteLock_upgrade; typedef boost::shared_lock< Lock > ReadLock; Lock myLock; void writer_thread() { WriteLock_uniq w_lock(myLock); std::string threadId = boost::lexical_cast<std::string>(boost::this_thread::get_id()); std::cout << "writer holding lock, threadid " << threadId << " " << std::endl; Sleep(1000); std::cout << "END, threadid " << threadId << " " << std::endl; }; void writer_upgrade_thread() { WriteLock_upgrade w_lock(myLock); std::string threadId = boost::lexical_cast<std::string>(boost::this_thread::get_id()); std::cout << "UPgraded writer holding lock, threadid " << threadId << " " << std::endl; Sleep(1000); std::cout << "END, threadid " << threadId << " " << std::endl; }; void reader_thread() { ReadLock r_lock(myLock); std::string threadId = boost::lexical_cast<std::string>(boost::this_thread::get_id()); std::cout << "reader holding lock, threadid " << threadId << " " << std::endl; Sleep(1000); std::cout << "END, threadid " << threadId << " " << std::endl; }; int test_RW_lock() { boost::thread_group threads; threads.create_thread(boost::bind(reader_thread)); threads.create_thread(writer_upgrade_thread); threads.create_thread(writer_upgrade_thread); threads.create_thread(boost::bind(reader_thread)); threads.create_thread(boost::bind(reader_thread)); threads.create_thread(boost::bind(reader_thread)); threads.create_thread(boost::bind(reader_thread)); threads.create_thread(writer_upgrade_thread); threads.create_thread(writer_upgrade_thread); threads.create_thread(boost::bind(writer_thread)); threads.join_all(); }