我正在实现一对进程间通信的类,其中一个进程将是唯一的作者,并且会有很多读者。一个班级处理阅读;一个处理写作。为了防止任何其他进程成为作者,我想要一个作家类的单个对象,它在整个生命周期内保持一个可升级的锁在boost::named_upgradable_mutex
上。为此,作者类有一个类型为boost::interprocess::upgradable_lock
的成员变量,当构造对象时,这个成员变量被交给了互斥体。当编写器进程写入时,它调用写入器类的Write()方法,该方法应该将该锁升级为独占,执行写操作,并将独占锁自动降级为仅可再次升级。如何在一个对象的生命周期内持有Boost升级对象?
我已经成功实现了第一部分 - 通过遵循Lock Transfers Through Move Semantics上的Boost文档,在我的作家类的Write()方法中将锁升级为独占锁。然而,第二部分 - 将锁降级为可升级 - 会产生一个类型为boost :: interprocess :: upgradable_lock的新局部变量,它将在Write()返回时超出范围并释放互斥锁。我需要将这个可升级的锁放回到我的类的upgradable_lock成员变量中,这样升级能力将完全保留在我的作者对象中。什么是最好的方法来做到这一点?我设法做出的唯一事情是在返回之前将局部变量与我的成员变量交换。代码看起来像这样:
using boost::interprocess;
scoped_lock<named_upgradable_mutex> my_exclusive_lock(move(m_lock));
// do write here
upgradable_lock<named_upgradable_mutex> my_demoted_lock(move(my_exclusive_lock));
m_lock.swap(my_demoted_lock); // how else to do this?
这有效,但最后一行真的是违反直觉,花了我一段时间的思考。有没有更好的办法?是否可以将降级锁直接放入我的成员变量中?另外,重新使用成员变量来存储降级锁有没有意想不到的后果?
谢谢 - 非常全面,非常有帮助。奇怪的是,我今天早上阅读了右值引用,并意识到move()会比swap()更好,所以我实现了这个。由于偶然事件,读写器类只能使用POD类型,因此写操作是异常安全的。 – bythescruff