在标准容器线程上调用size()安全吗?

时间:2019-09-20 20:34:04

标签: c++ stl thread-safety race-condition stdlist

我有一个使用std列表容器的缓冲区。

一个工人在一侧推动元素,而另一线程从另一侧弹出。这两个线程在访问容器之前都使用互斥锁。

作为一种查看性能的方法,我需要查询容器的大小。但是,如果不需要的话,使用互斥量查询大小似乎有点过分。

问题是,有必要吗?

文档说明了如何致电size()(在“数据竞赛”部分下: 不访问任何包含的元素:安全地同时访问或修改它们。

2 个答案:

答案 0 :(得分:6)

  

问题是必要的吗?

是的。您可能在查询元素的大小时将其添加到列表中,这是未定义的行为。

规则是,如果您有多个线程访问共享库,并且其中至少有一个写入该对象,则必须具有同步性。如果没有,那将是数据争夺,这是未定义的行为。


根据您的修改:

不访问任何包含的元素:同时访问或修改它们是安全的。表示不访问或更改列表中的元素。这意味着您可以调用size(),而不必担心它会修改列表中的任何元素。在此之前,它已经访问了容器。是访问不是线程安全的。如果您在调用size时将元素添加到列表中,则获得的值是不确定的。

答案 1 :(得分:0)

简短的回答是:“是”。

要确定相互排斥的需求,需要查看所涉及功能的“数据竞争”规范。在这种情况下,std::list push/pop函数规范说容器已被修改。虽然size函数规范指出容器可访问的

通常,每当多个线程访问或修改某些数据,并且至少一个线程修改了某些数据时,所有访问和修改都必须通过互斥来保护。