【发布时间】:2013-12-04 14:01:09
【问题描述】:
我有一个可爱的小问题,我有一个 STL 容器(unordered_map 或向量),它可以被任意数量的线程读取和扩展,我希望尽可能高效地完成它(即减少锁定延迟尽可能)。
现在,最简单的部分是使用共享锁进行读取,使用排他锁进行扩展,所以我可能会这样做:
boost::shared_lock myLock;
std::unordered_map myMap;
...
myLock.lock_shared();
//try looking up key
myLock.unlock_shared();
if(!success) {
myLock.lock();
//retry looking up key
if(!success) {
myMap[key] = value;
}
myLock.unlock();
}
虽然我认为这在一般情况下相当有效,但如果myMap 决定需要重新分配其内部存储,则持有独占锁的时间可能会爆炸。持有锁的时间可能会达到几百微秒,并且在此期间它会阻塞任何试图读取容器的线程。
有人知道在重新分配存储时可用于避免阻塞所有读取线程的习语吗?
当然,我知道这些延迟不会累积来降低整体性能的数学公式,但是如果我能以某种方式限制可能的延迟,我会更开心。
【问题讨论】:
-
您可能想要一个在开发时考虑到并发访问的容器,因此它只会在扩展期间的关键点包含适当的锁定(例如,它可以分配新的存储空间并进行复制在锁之外,然后只需锁定换入)。我不相信 STL/Boost 的工作方式 - 因此您当前的粗粒度锁定方法。可能有其他库已经以这种方式工作,或者您可能必须推出自己的...
-
也许在读取线程中使用
try_lock_shared()会很好,这样它们就不会在尝试获取锁时被阻塞。当然,这是假设他们在无法获得锁时可以做其他事情。
标签: c++ multithreading stl