multithreading - Reader/Writer Locks in C++

时间:2023-03-09 06:29:17
multithreading - Reader/Writer Locks in C++

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();
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();
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();
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();
}