【问题标题】:boost shared_mutex destructor提升 shared_mutex 析构函数
【发布时间】:2014-10-10 13:18:35
【问题描述】:

我有一个多线程应用程序,它必须经常读取一些数据,并且偶尔会更新这些数据。我在使用 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 中

【问题讨论】:

    标签: multithreading visual-studio boost mutex


    【解决方案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 以便调用者可以选择显式 @ 987654329@锁,或者只是让它被守卫自动释放。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多