我希望有人可以就多个线程如何写入公共(public)容器(例如 map )提出建议。在某些线程可能使用 Boost 和 C++ 共享相同 key 的情况下
映射的类型可能是:std::map,不同的线程访问该对象以修改不同的数据成员。每个线程是否会在命中 unique_lock 后等待当前线程完成,然后再继续?
会不会像这个例子一样简单到每个线程进入临界区:
//somewhere within the code
boost::unique_lock mutex;
void modifyMap(const std::string& key,const unsigned int dataX,
const unsigned int dataY)
{
// would each thread wait for exclusive access?
boost::unique_lock<boost::shared_mutex> lock (mutex);
// i now have exclusive access no race conditions;
m_map.find(key)->second.setDataX(dataX);
m_map.find(key)->second.setDataX(dataY);
}
提前致谢
最佳答案
您应该创建数据结构的线程安全实现。它可以是基于锁的(例如通过使用互斥锁实现)或无锁的(使用 C++11 和 boost 支持的原子操作或内存排序)。
我可以简要描述一下基于锁的方法。例如,你可能想设计一个线程安全的链表。如果您的线程只执行读取操作,那么一切都是安全的。另一方面,如果您尝试写入此数据结构,您可能需要列表中的前一个和下一个节点指针(如果它是双链接的,您需要更新它们的指针以指向插入的节点)并且在修改它们时其他一些线程可能会读取不正确的指针数据,因此您需要锁定要在其间插入新节点的两个节点。这会创建序列化(其他线程等待解锁互斥量)并降低并发的可能性。
Anthony Williams 所著的“C++ 并发:实用多线程”一书第 171 页的 list 6.11 中提供了带有查找表的完整示例。这本书本身是使用最新的 C++ 标准进行多线程编程的良好开端,因为本书的作者还设计了 boost::thread 和 C++11 线程库。
更新:为了使您的示例适用于读/写(如果您需要更多操作,您还需要保护它们)您最好使用 boost::shared_mutex,它本质上允许多读单写访问:如果一个线程想要写而不是要获取独占锁,所有其他线程将不得不等待。这是一些代码:
template <typename mapType>
class threadSafeMap {
boost::shared_mutex map_mutex;
mapType* m_map;
public:
threadSafeMap() {
m_map = new mapType();
}
void modifyMap(std::string& key,const unsigned int dataX,
const unsigned int dataY)
{
//std::lock_guard in c++11. std::shared_mutex is going to be available in C++14
//acquire exclusive access - other threads wait
boost::lock_guard<boost::shared_mutex> lck(map_mutex);
m_map.find(key)->second.setDataX(dataX);
m_map.find(key)->second.setDataX(dataY);
}
int getValueByKey(std::string& key)
{
//std::lock_guard in c++11. std::shared_mutex is going to be available in C++11
//acquire shared access - other threads can read. If the other thread needs access it has to wait for a fully unlocked state.
boost::shared_lock<boost::shared_mutex> lck(map_mutex);
return m_map.getValue(key);
}
~threadSafeMap() {
delete m_map;
}
};
Lock-guard 对象在生命周期结束时被破坏并且互斥量被解锁。 mapType 模板可以替换为您的 map 类型。
关于c++ - 多个线程执行写入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17898647/