【发布时间】:2015-07-06 09:13:36
【问题描述】:
我有一个Dinosaur 对象列表,可以添加、删除这些对象,恐龙本身需要喂食。这一切都发生在高度多线程的环境中,因此列表受互斥体保护。
static Mutex s_dinosaurMutex;
static vector<Dinosaur> s_dinosaurList;
void AddDinosaur(const Dinosaur& dinosaur)
{
s_dinosaurMutex.Lock();
s_dinosaurList.push_back(dinosaur);
s_dinosaurMutex.Unlock();
}
void RemoveDinosaur(const Dinosaur& dinosaur)
{
s_dinosaurMutex.Lock();
vector<IMadderReceiver*>::iterator it = find(s_dinosaurList.begin(), s_dinosaurList.end(), dinosaur);
if (it != s_dinosaurList.end())
s_dinosaurList.erase(it);
s_dinosaurMutex.Unlock();
}
void FeedDinosaur(const Dinosaur& dinosaur)
{
s_dinosaurMutex.Lock();
vector<IMadderReceiver*>::iterator it = find(s_dinosaurList.begin(), s_dinosaurList.end(), dinosaur);
if (it != s_dinosaurList.end())
(*it).Feed(); // Feeding a dinosaur can take a long time, ~ 1 second
s_dinosaurMutex.Unlock();
}
现在问题出在喂食上。这可能需要很长时间,但如果多个线程同时喂食相同(或不同)的恐龙,那绝对没问题。因此,馈送过程不应停止其他 FeedDinosaur 调用,尽管它应该为 Add 和 Remove 调用停止,并等待这些调用完成。目前的行为是许多线程正在排队等待喂食恐龙,这使得系统陷入僵局。
是否有一种特殊的(类似互斥的)设计模式允许这种需要只读访问的正常线程的行为?
【问题讨论】:
-
是的,这就是“读写锁”的用途。
-
除了@Sneftel 提到的之外,我还建议在您的互斥体周围使用 RAII 包装器,例如
std::lock_guard,以确保在函数的每个退出路径上释放互斥体 -
Reader/Writer Locks in C++ 的可能重复项
标签: c++ multithreading mutex