Tôi có một ứng dụng máy chủ đa luồng cần các khóa mutex trên một số bộ nhớ dùng chung.Ví dụ về cách sử dụng các đột biến nâng cấp có thể nâng cấp
Bộ nhớ dùng chung về cơ bản là bản đồ sTL vv.
Phần lớn thời gian tôi chỉ đọc từ bản đồ. Nhưng, tôi cũng cần phải thỉnh thoảng thêm vào nó.
ví dụ: typedef std :: Bản đồ MessageMap; Bản đồ thư MessageMap; tăng: 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.
}
EDIT: Tôi có thể gây nhầm lẫn với các loại khóa khác nhau.
Sự khác biệt giữa chia sẻ/nâng cấp và độc quyền. tức là tôi không hiểu giải thích. Có vẻ như bạn chỉ muốn cho phép nhiều người đọc, quyền truy cập được chia sẻ là tất cả những gì bạn muốn có. Và để ghi vào bộ nhớ chia sẻ của bạn, bạn chỉ cần truy cập nâng cấp. Hay bạn cần độc quyền? Lời giải thích trong tăng là bất cứ điều gì nhưng rõ ràng.
Quyền truy cập nâng cấp có được do bạn có thể viết hay không. Nhưng chia sẻ có nghĩa là bạn chắc chắn sẽ không viết là những gì nó có nghĩa là?
EDIT: Hãy để tôi giải thích những gì tôi muốn làm với một chút rõ ràng hơn. Tôi chưa hài lòng với câu trả lời.
Đây là ví dụ trên một lần nữa nhưng với ví dụ về một số mã mà tôi đang sử dụng. Chỉ là minh họa, không phải mã thực.
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?
}
Xin lỗi tôi nghĩ rằng có lẽ tôi muốn sử dụng boost :: upgrade_lock và boost :: upgrade_to_unique_lock. Có lẽ bạn có thể giải thích sự khác biệt giữa chúng. Xem câu hỏi đã chỉnh sửa của tôi. – Matt
@Matt H: xem câu trả lời đã chỉnh sửa. – ybungalobill
Với UpgradeLockable, có thể chỉ có một luồng trong trạng thái đó nhưng một số có thể trong SharedLockable là đúng? do đó, để khóa nâng cấp trở thành khóa duy nhất, tất cả khóa được chia sẻ cần phải được mở khóa chính xác? – Matt