在插入其他线程时有效地迭代映射

时间:2012-08-07 14:01:19

标签: c++ data-structures thread-safety

我有一个std::map < std::string, std::string >,它从一个线程以不规则的间隔添加了值(但经常需要非常快),偶尔会删除一组条目。

我需要从另一个线程将地图快照作为文本转储到用户的调试日志命令。

显然,在可以更新调试信息的情况下迭代输出调试信息的地图不是线程安全的,因此我在转储数据之前正在读取锁定(mutex),并且每次插入或删除都会写入锁定。这工作正常,但我无法真正锁定地图这么长时间,它会延迟传入更新的处理过多。

我不相信我可以锁定和解锁每个项目的调试转储线程,因为从其他线程修改映射会使我认为的迭代器无效。

有什么方法可以安全地做到这一点,而不必在我写出来的时候对整个数据结构取出读锁定,这样新的值仍然可以快速插入?我意识到,如果我可以在迭代过程中添加和删除值,那么我将无法得到一个保证一致的数据视图,但只要知道它是安全的。

如果没有办法使用地图,有人可以建议我可以使用的任何其他数据结构吗?

编辑:我希望有一个解决方案,这意味着我在添加项目时不需要购买昂贵的锁。

1 个答案:

答案 0 :(得分:4)

目前我可以看到两种解决方案:

  1. (简单,但可能仍需要太长时间):在锁定时复制地图(或分配给另一个容器),然后在未锁定的情况下将本地副本转储到调试日志
  2. (还有一些工作):通过队列将地图的更新委托给另一个线程。如果另一个线程是转储到调试日志的线程,那么您不再需要锁定。这样,只有在访问队列时才会锁定快速线程。