c++ - 多个线程执行写入?

标签 c++ multithreading boost

我希望有人可以就多个线程如何写入公共(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/

相关文章:

c++ - 为什么模板函数不能将指向派生类的指针解析为指向基类的指针

c++ - (shared_ptr+weak_ptr)兼容原始指针的设计

.net - 检查AutoResetEvent状态

c++ - 未定义的 boost 引用

c++ - Boost Spirit x3条件(三元)运算符解析器(后续问题)

c++ - 分析 stable_sort

c++ - SxS list 中的程序集身份名称

c# - 编写 C# TSR 的公认方法是什么?

java并发: CopyOnWriteArrayList strategy

c++ - 哪些库对 std::make_shared 使用了 "We Know Where You Live"优化?