在使用boost共享互斥锁

时间:2017-06-14 21:02:51

标签: c++ multithreading boost

我正在使用C ++多线程程序,该程序必须使用boost shared_mutex在类中读取和写入一些属性。该程序在执行时创建A类的多个对象实例。此类A具有静态shared_mutex,由所有A类对象共享。如果需要在其中一个对象实例中写入该类的某个属性,则特定对象实例需要通过将其升级为唯一锁来获得对共享互斥锁的独占访问权。但是,在执行此操作之前,set方法检查类实例是否拥有锁,这对我来说有点奇怪。

这或多或少类A hpp文件的样子:

#include <boost/thread.hpp>

class A{
    private:
        //Private methods
        void setAttribute(boost::upgrade_lock<boost::shared_mutex>& lock, const bool value);
        //Private variables
        static boost::shared_mutex mainMutex;
        mutable bool attribute;
    public:
        //... Some public methods using setAttribute
}

这就是A类cpp文件的样子:

void A::setAttribute(boost::upgrade_lock<boost::shared_mutex>& lock, const bool value)
{
    (void)lock;
    assert(lock.owns_lock());

    //get exclusive access to the lock
    const boost::upgrade_to_unique_lock<boost::shared_mutex> ulock(lock);
    attribute = value;
}

所以,我的问题是为什么我需要检查传递的锁是否拥有锁,因为方法setAttribute是私有的,并且它仅由类中的方法使用。在任何情况下我都应该考虑这样做吗?

1 个答案:

答案 0 :(得分:0)

此处存在int[] array1and2 = new int[namesArrayList1.length + namesArrayList2.length]; System.arraycopy(namesArrayList1, 0, array1and2, 0, namesArrayList1.length); System.arraycopy(namesArrayList2, 0, array1and2, namesArrayList1.length, namesArrayList2.length); 条件,以避免在编译期间使用(void) lock;之类的内容时出现编译错误。这表明编译器会停止所有未使用变量的警告(以及其他内容)。当程序员不知道该变量是否会被使用,但不想破坏构建时,它有时会用在代码中。

g++ -DNDEBUG -Wall -Werror -pedantic方法表示特定对象已获得锁的所有权。或者换句话说,锁定对象。如果它是共享锁,则多个对象可以拥有&#39;它。 &#39;资&#39;是同义词&#39;被此对象锁定&#39;。如果它是一个独特的锁,那么只有一个对象可以拥有它。

owns_lock()可能只适用于调试版本,没有它,代码会通过尝试静默地将锁升级为唯一锁而失败;即使在线程不拥有锁定的情况下(例如,它已被解锁)。如果这是真的,那么升级将无声地失败。

例如,如果禁用assert()时发生了如下操作的某些顺序,则代码将无声地失败:

assert

boost::upgrade_lock<boost::shared_mutex> lock(this->mainMutex); lock.unlock(); this->setAttribute(lock, false); 调用获取锁的升级所有权。意味着有合同说这个对象可以升级锁。

upgrade_lock调用通过停止实际将共享锁升级到唯一锁,直到任何其他共享所有者释放锁。如果在调用此对象时该对象不拥有该锁,则它将无声地将锁升级为唯一锁。

TLDR;我怀疑作者的意图是将互斥代码保持为类的私有,但是想要设置一个断言,以防在upgrade_to_unique_lock之前的某处意外调用unlock()。