提升shared_mutex析构函数

时间:2014-10-10 13:18:35

标签: multithreading visual-studio boost mutex

我有一个多线程应用程序,必须经常读取一些数据,偶尔会更新数据。我通过使用unique_lock和使用upgrade_lock进行读取时出现问题 有我的问题的例子:

void unlock(){
    test.stream = 0;
    test.mtx.unlock();
}

void lock_mtx(int i){
    boost::unique_lock<boost::shared_mutex> lock(test.mtx);
    test.stream = i;
    boost::this_thread::sleep_for(boost::chrono::milliseconds(10000));
    unlock();
    boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
}

当我破坏lock时,此线程已经解锁了互斥锁,有时它被另一个线程锁定,但是析构函数再次释放它。破坏锁定后(在第一个线程中)第三个线程占用互斥锁,我在一个时刻有两个编写器

void lock_mtx(int i){
    boost::upgrade_lock<boost::shared_mutex> lock(test.mtx);
    read_from_locked();
    boost::this_thread::sleep_for(boost::chrono::milliseconds(5000));
    boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);
    write_to_locked();
    boost::this_thread::sleep_for(boost::chrono::milliseconds(10000));
}

第二个问题是,当某个线程占用upgrade_lock时,其他线程无法读取共享对象

MS VisualStudio 2013和Windows8 x64中都出现了这两个问题

1 个答案:

答案 0 :(得分:1)

void lock_mtx(int i)
{
    {
        boost::unique_lock<boost::shared_mutex> lock(test.mtx);
        test.stream = i;
        boost::this_thread::sleep_for(boost::chrono::milliseconds(10000));
    }
    boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
}

unique_locklock_guard的目的是在超出范围时自动解锁互斥锁。这种模式称为RAII。

经验法则:切勿在(基本|共享)可锁定对象上手动调用lock() / unlock()。这是反模式,因为

  • 很难做到正确(想到例外安全)
  • 它通常表示代码异味(在不同的方法调用中保持锁定)。如果你甚至需要这个,考虑让RAII锁定保护(lock_guardunique_lock)成为包含类的成员,或者返回unique_lock以便调用者可以选择明确地 adopt锁定,或者让它自动由警卫释放。