我正在實現一對進程間通信的類,其中一個進程將是唯一的作者,並且會有很多讀者。一個班級處理閱讀;一個處理寫作。爲了防止任何其他進程成爲作者,我想要一個作家類的單個對象,它在整個生命週期內保持一個可升級的鎖在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