【问题标题】:When a map is copied to another existing map, what happend in details?当一个地图被复制到另一个现有地图时,具体发生了什么?
【发布时间】:2021-07-10 09:13:04
【问题描述】:
int main ()
{
  std::map<char,int> foo,bar;

  foo['x']=100;
  foo['y']=200;
  foo['z']=300;

  bar['x']=100;
  bar['y']=2000;
  bar['zz']=400;

  foo=bar;
  return 0;
}

是不是 foo 清空所有元素,然后遍历 bar 构造新元素的过程? 还是 foo 遍历 foo 和 bar 的所有键,然后只执行必要的修改? 我遇到过这样的情况,短时间内无法通过key访问map。原因可能是使用“=”分配(foo = bar)更新地图。 是否可以通过使用 std::swap (foo.swap(bar)) 来解决这个问题? 还是必须使用读写锁?

【问题讨论】:

  • 修改 map 不是原子的(即使是交换),所以在多线程情况下,你必须保护更改(互斥锁,...)。
  • 分配不是线程安全的,如果你想知道的话。你需要一个原子映射,或者做一个原子交换,或者使用一个锁来解决它。 (请注意,swap 成员函数或 std::swap 特化在 C++ 规范中未标记为原子或线程安全。)
  • 您正在调用 std::map::operator=,所以这里是该函数的文档:en.cppreference.com/w/cpp/container/map/operator%3D
  • “我遇到过这样的情况,短时间内不能通过key访问map”我们说的是多线程吗?如果不是,不清楚你的意思,如果是,你应该显示有问题的代码,因为你发布的代码没有

标签: c++ c++11 stl swap stdmap


【解决方案1】:

foo 清除所有元素然后遍历 bar 构造它的新元素的过程是这样的吗?还是 foo 遍历 foo 和 bar 的所有键,然后只执行必要的修改?

你在那里做的是一个副本分配。这意味着首先将清除foo,然后将bar 中的元素复制到其中。

我遇到过这样的情况,短时间内无法通过key访问地图。

我假设你的多线程,这就是你遇到这个问题的原因。正如@Jarod42@Some程序员老兄所说,分配或修改映射不是线程安全的,这意味着在修改之前必须锁定资源。您可以使用std::mutex 来执行此操作。

是否可以使用 std::swap (foo.swap(bar)) 来解决这个问题?

规范没有说明它是线程安全的,因此最好确保在交换之前锁定资源。

还请注意,在使用std::map&lt;,&gt;::swapstd::swap 时,您不仅将值从bar 分配给foo,还可以通过分配foo 的值来更改bar。和foo = bar;不一样。

附加:std::atomic

【讨论】:

  • 非常感谢
猜你喜欢
  • 2015-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
相关资源
最近更新 更多