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

 

posted @ 2015-01-20 16:57  ScottGu  阅读(246)  评论(0编辑  收藏  举报