假设我有一堂课:
class A
{
private:
std::vector<MyObject> history;
std::mutex historyLock;
}
该类初始化了多个线程,这些线程获取互斥量并写入历史向量。假设然后我有另一个班级想要阅读该列表:
class B
{
public:
B(A instanceA)
{
// I want to read the list here in a thread safe way
}
}
我的直觉告诉我在class A
中公开一个名为GetHistory()
的方法,该方法将锁定互斥锁,复制列表并返回副本。
是否有一种方法可以读取B类中的列表而不会产生复制操作的费用?
答案 0 :(得分:2)
有几种方法可以解决此类问题。一种方法是使用更复杂的结构来存储您的历史记录,例如不可变的向量。 (一个不变的向量将迭代性能换成廉价的副本。)但是,仅使用标准C ++,我认为最简单的方法是向接受回调的类A添加遍历成员函数模板:
template <class F> void TraverseHistory(F&& callback)
{
std::lock_guard guard{ historyMutex };
for (auto const& item : history)
{
callback(item);
}
}
如果您不想使用功能模板,也可以使用std::function
:
void TraverseHistory(std::function<void(MyObject const&)> const& callback);
另一种选择是将对整个向量的引用传递给您的回调。通过这种方法,功能模板将如下所示:
template <class F> void ReadHistory(F&& callback)
{
std::lock_guard guard{ historyMutex };
callback(std::as_const(history));
}