我有一個多線程的服務器應用程序,它需要對某些共享內存進行互斥鎖。如何使用boost升級互斥體的示例
共享內存基本上都是STL地圖等
很多時候我只是從地圖上讀出。 但是,我也需要偶爾加入它。
例如 typedef std :: map MessageMap; MessageMap msgmap; boost:shared_mutex access_;
void ProcessMessage(Message* message)
{
// Access message... read some stuff from it message->...
UUID id = message->GetSessionID();
// Need to obtain a lock here. (shared lock? multiple readers)
// How is that done?
boost::interprocess::scoped_lock(access_);
// Do some readonly stuff with msgmap
MessageMap::iterator it = msgmap.find();
//
// Do some stuff...
// Ok, after all that I decide that I need to add an entry to the map.
// how do I upgrade the shared lock that I currently have?
boost::interprocess::upgradable_lock
// And then later forcibly release the upgrade lock or upgrade and shared lock if I'm not looking
// at the map anymore.
// I like the idea of using scoped lock in case an exception is thrown, I am sure that
// all locks are released.
}
編輯: 我可能會混淆不同的鎖類型。
共享/升級和獨家之間有什麼區別。 即我不明白解釋。 聽起來好像你只是想允許很多讀者,共享訪問就是你想要的。要寫入共享內存,您只需要升級訪問權限。或者你需要獨家?提振的解釋是非常明確的。
是否因爲可能寫入而獲得升級訪問權限。但共享意味着你肯定不會寫這是什麼意思?
編輯:讓我解釋一下我想要做的更清晰一點。我還不滿意答案。
這裏是一遍又一遍的例子,但也有一些我正在使用的代碼的例子。 只是一個說明,而不是實際的代碼。
typedef boost::shared_mutex Mutex;
typedef boost::shared_lock<Mutex> ReadLock;
typedef boost::unique_lock<Mutex> WriteLock;
Mutex mutex;
typedef map<int, int> MapType; // Your map type may vary, just change the typedef
MapType mymap;
void threadoolthread() // There could be 10 of these.
{
// Add elements to map here
int k = 4; // assume we're searching for keys equal to 4
int v = 0; // assume we want the value 0 associated with the key of 4
ReadLock read(mutex); // Is this correct?
MapType::iterator lb = mymap.lower_bound(k);
if(lb != mymap.end() && !(mymap.key_comp()(k, lb->first)))
{
// key already exists
}
else
{
// Acquire an upgrade lock yes? How do I upgrade the shared lock that I already have?
// I think then sounds like I need to upgrade the upgrade lock to exclusive is that correct as well?
// Assuming I've got the exclusive lock, no other thread in the thread pool will be able to insert.
// the key does not exist in the map
// add it to the map
{
WriteLock write(mutex, boost::adopt_lock_t()); // Is this also correct?
mymap.insert(lb, MapType::value_type(k, v)); // Use lb as a hint to insert,
// so it can avoid another lookup
}
// I'm now free to do other things here yes? what kind of lock do I have here, if any? does the readlock still exist?
}
對不起,我想也許我想使用boost :: upgrade_lock和boost :: upgrade_to_unique_lock。也許你可以解釋他們之間的差異。看到我編輯的問題。 – Matt 2010-10-09 09:55:31
@Matt H:見編輯答案。 – ybungalobill 2010-10-09 18:49:26
有了UpgradeLockable,那裏只能有一個線程處於該狀態,但有幾個可以在SharedLockable中是正確的?所以爲了使升級鎖成爲唯一鎖,所有共享鎖都需要解鎖正確? – Matt 2010-10-10 03:23:38