使用boost模板函数实现读写锁

介绍

  • shared_mutex即读写锁,不同与我们常用的独占式锁mutex,shared_mutex是共享与独占共存的锁,实现了读写锁的机制,即多个读线程一个写线程,通常用于对于一个共享区域的读操作比较频繁,而写操作比较少的情况。
  • 读写锁比起mutex具有更高的适用性,具有更高的并行性,可以有多个线程同时占用读模式的读写锁,但是只能有一个线程占用写模式的读写锁,读写锁的基本规则可以总结为“写优先,读共享,交叉互斥“,具体表现为读写锁的三种状态:

        (1)当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞。(交叉互斥)
        (2)当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都可以得到访问权,但是以写模式对它进行加锁的线程将会被阻塞。(读共享,交叉互斥)
        (3)当读写锁在读模式的锁状态时,如果有另外的线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁的请求,这样可以避免读模式锁长期占用,而等待的写模式锁请求则长期阻塞。(写优先)

  • 注:其实在读者-写者问题中,有读者优先和写者优先两种模式,只是在boost中的shared_mutex默认的实现是写者优先,这其实也是有道理的,因为在我们总是希望读到的数据是最新的,这就得保证写者优先。
  • 下面通过一个 boost::shared_mutex的应用实例来反应其锁机制,该例子中我们建立多个读者线程,两个写者线程,程序的实际运行结果很直接的反应了shared_mutex应用情况。

代码

#include <boost/thread/thread.hpp>
#include <boost/ref.hpp>
#include <string>

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

//读线程
void read_thread(std::string &name){
    boost::shared_lock<boost::shared_mutex> lock(global_mutex);//读锁定 shared_lock
    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::unique_lock<boost::shared_mutex> lock(global_mutex);//写锁定 unique_lock
    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";

    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.join_all();

    return 0;
}

程序运行结果

结论

  • 从运行结果中可以看出,如果是读者获得了shared_mutex,则其他读者可以同时抢占资源,但如果是写者获得了shared_mutex,则其他的写者或读者都不能进入临界区,即同时只有一个写者能进入临界区。 

猜你喜欢

转载自blog.csdn.net/CHYabc123456hh/article/details/111567384