锁定 std::map C++

Posted

技术标签:

【中文标题】锁定 std::map C++【英文标题】:Lock std::map C++ 【发布时间】:2012-07-08 12:46:56 【问题描述】:

在我的多线程应用程序中使用std:map 时遇到问题。当线程写入该对象时,我需要锁定地图对象。并行读取此对象的另一个线程应该存储直到写入过程完成。

示例代码:

std::map<int, int> ClientTable;

int write_function() //<-- only one thread uses this function

  while(true)
  
    //lock ClientTable
    ClientTable.insert(std::pair<int, int>(1, 2)); // random values
    //unlock ClientTable

    //thread sleeps for 2 secs
  


int read_function()  //<--- many thread uses this function

  while(true)
  
     int test = ClientTable[2]; // just for test
  

如何锁定这个 std::map 对象并正确同步这个线程?

【问题讨论】:

您可能希望将read_function 更改为使用mapfind 成员函数而不是operator[],因为后者实际上可以修改map。通常这是一种轻微的烦恼(在最坏的情况下),但在这种情况下,会变得更加严重。 【参考方案1】:

看起来您需要的是一个典型的读写锁,它允许任意数量的读取器,但只有一个写入器。你可以看看boost的shared_mutex。

其他使用示例可以在这里找到:Example for boost shared_mutex (multiple reads/one write)?

【讨论】:

map 仅对读取操作是线程安全的,我需要在写入器工作时锁定所有其他写入器和读取器。当读者工作时不需要锁。我该如何使用 shared_mutex 呢?我对此一无所知(。谢谢! @Robert:这个锁就是这样做的:当一个线程想要获取写锁时,所有其他线程都被锁定,但是当一个线程想要读取时,任何其他线程都可以同时读取(除非有人在写,就像我说的那样)。检查我链接的问题中的示例以了解如何使用它。 正如 ChristianStieber 所建议的,read_function 是一个误导性名称,因为std::mapoperator[] 可以(将)实际修改地图,如果不是,则插入带有指定键的项目已经存在。【参考方案2】:

好吧,由于 std::map 没有内置锁,因此您必须使用单独的锁来保护地图。如果映射是由该锁保护的所有内容,您可以将映射子类化以在其中添加锁以及“锁定”和“解锁”调用,但如果锁也将用于其他项目,那么它可能不是最好的主意这样做。

至于“如何正确同步”——这对于手头的应用程序非常具体。但是,对于给出的示例,您还必须在读取操作周围插入锁定/解锁调用。

如果您有读/写锁,这也可能是其中一个很好的应用程序。

【讨论】:

如果锁保护地图和其他相关对象,最好将地图、锁和其他相关对象捆绑到一个类中。该类可以提供一个函数,该函数在持有锁的同时调用地图的insert 函数。 operator[] 同上(当然返回非引用右值)。

以上是关于锁定 std::map C++的主要内容,如果未能解决你的问题,请参考以下文章

最小化锁争用 c++ std::map

使用线程不安全的静态变量锁定嵌套函数

从两个线程访问锁定映射和向量

如何以线程安全的方式使用`std::unordered_map`?

C++:检查计算机是不是被锁定

C++ 锁定文件 Windows 阻塞模式