使用named_mutex和named_condition配合实现读写锁

15 篇文章 0 订阅
13 篇文章 0 订阅

代码

  • 代码的名称是read_write_mutex.h
  • 初步优化
  • 如果涉及到进程挂掉了,造成进程堵塞,如何解决?还未涉及
#include <boost/interprocess/sync/named_condition.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>

namespace bip = boost::interprocess;
namespace chy{
    class shared_mutex
    {
    private:
        class state_data{
        public:
            state_data() :
                shared_count(0),
                exclusive(false),
                exclusive_waiting_blocked(false)
            {}

            void assert_free() const{
                BOOST_ASSERT( ! exclusive );
                BOOST_ASSERT( shared_count==0);
            }

            void assert_locked() const{
                BOOST_ASSERT( exclusive);
                BOOST_ASSERT( shared_count==0);
            }

            void assert_lock_shared() const{
                BOOST_ASSERT( !exclusive);
                BOOST_ASSERT( shared_count>0 );
            }

            bool can_lock() const{
                return ! (shared_count || exclusive);
            }

            void exclusive_blocked (bool blocked){
                exclusive_waiting_blocked = blocked;
            }

            void lock(){
                exclusive = true;
            };

            void unlock(){
                exclusive = false;
                exclusive_waiting_blocked = false;
            }

            bool can_lock_shared() const{
                return !(exclusive || exclusive_waiting_blocked);
            }

            bool more_shared() const{
                return shared_count > 0;
            }

            uint8_t get_shared_count() const{
                return shared_count;
            }

            uint8_t lock_shared(){
                return ++shared_count;
            }
            uint8_t unlock_shared(){
                return --shared_count;
            }
            //TODO shared_count 的类型最好不要使用unsigned
            unsigned shared_count;//读者数量
            bool exclusive;//表示已经加了写锁,进入互斥状态
            bool exclusive_waiting_blocked;//表示即将加写锁,当其为true的时候,不可以加读锁,此时写锁竞争
        };
            state_data state;
            //TODO 将文件的名字和named_mutex和named_condition绑定在一起
            bip::named_mutex state_change{bip::open_or_create,"mutex"};
            bip::named_condition shared_cond{bip::open_or_create,"read"};
            bip::named_condition exclusive_cond{bip::open_or_create,"write"};

            void release_waiters(){
                exclusive_cond.notify_one();
                shared_cond.notify_all();
            }

    public:
        shared_mutex()=default;
        ~shared_mutex()=default;
        void lock_shared(){
           boost::unique_lock<bip::named_mutex>lk(state_change);
            while (!state.can_lock_shared()){
                shared_cond.wait(lk);
            }
            state.lock_shared();
        }

        bool try_lock_shared(){
            boost::unique_lock<bip::named_mutex>lk(state_change);
            if (!state.can_lock_shared()){
                return false;
            }
            state.lock_shared();
            return true;
        }

        void unlock_shared(){
            boost::unique_lock<bip::named_mutex>lk(state_change);
            state.assert_lock_shared();
            state.unlock_shared();
            if (! state.more_shared()){
                state.exclusive_waiting_blocked = false;
                release_waiters();
            }
        }

        void lock(){
            boost::unique_lock<bip::named_mutex>lk(state_change);
            while (state.shared_count || state.exclusive){
                state.exclusive_waiting_blocked=true;
                exclusive_cond.wait(lk);
            }
            state.exclusive=true;
        }

        bool try_lock(){
            boost::unique_lock<bip::named_mutex>lk(state_change);
            if (state.shared_count || state.exclusive){
                return false;
            } else{
                state.exclusive=true;
                return true;
            }
        }
        void unlock(){
            boost::unique_lock<bip::named_mutex>lk(state_change);
            state.assert_locked();
            state.exclusive= false;
            state.exclusive_waiting_blocked= false;
            state.assert_free();
            release_waiters();
        }
    };
}//namespace chy

测试程序

#include <boost/thread/thread.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/ref.hpp>

#include "read_write_mutex.h"

#include <string>

chy::shared_mutex global_mutex;
int global_num = 10;//全局变量,写者改变全局变量,读者读全局变量
namespace bip = boost::interprocess;

//读线程
void read_thread(std::string &name){
    boost::shared_lock<chy::shared_mutex> lock{global_mutex};
    printf("线程%s抢占了资源,global_num = %d\n",name.c_str(),global_num);
    boost::this_thread::sleep(boost::posix_time::seconds(1));
    printf("线程%s释放了资源...\n",name.c_str());
}

//写线程
void write_thread(std::string &name){
    boost::lock_guard<chy::shared_mutex> lock{global_mutex};
    global_num++;//写线程改变数据的数值
    printf("线程%s抢占了资源,global_num = %d\n",name.c_str(),global_num);
    boost::this_thread::sleep(boost::posix_time::seconds(1));
    printf("线程%s释放了资源...\n",name.c_str());
}

int main(){
    std::string read_thread_r1 = "read_thread_r1";
    std::string read_thread_r2 = "read_thread_r2";
    std::string read_thread_r3 = "read_thread_r3";
    std::string read_thread_r4 = "read_thread_r4";
    std::string read_thread_r5 = "read_thread_r5";
    std::string write_thread_w1 = "write_thread_w1";
    std::string write_thread_w2 = "write_thread_w2";
//    std::string write_thread_w3 = "write_thread_w3";
//    std::string write_thread_w4 = "write_thread_w4";

    boost::thread_group tg;
    tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r1)));
    tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r2)));
    tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r3)));
    tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r4)));
    tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r5)));
    tg.create_thread(boost::bind(write_thread,boost::ref(write_thread_w1)));
    tg.create_thread(boost::bind(write_thread,boost::ref(write_thread_w2)));
//    tg.create_thread(boost::bind(write_thread,boost::ref(write_thread_w3)));
//    tg.create_thread(boost::bind(write_thread,boost::ref(write_thread_w4)));
    tg.join_all();

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值